Abu Bäkr
Abu Bäkr

Reputation: 333

How to use new collectionView in a subclass?

I have a baseController in which I have setup a topView. In that topView, I am using a UICollectionView named BaseCollectionViewCell. Now I have a new ViewController named HomeViewController which is subclass of BaseViewController. I need a new collectionView inside my HomeVC and so I made a new UICollectionViewCell class named HomeCollectionViewCell , but now when I am trying to use it, the application is crashing stating following error:

could not cast value of type 'MyApplicationName.BaseCollectionViewCell' to 'MyApplicationName.HomeCollectionViewCell'

How can I use the new collectionView in my HomeVC class? Any help would be appreciated.

BaseViewController

import UIKit
import WebKit

class BaseViewController: UIViewController {

let containerView: UIView = {
    let v = UIView()
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()

let topView:UIView = {
    let v = UIView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.backgroundColor = .navRedColor
    v.layer.cornerRadius = 45
    v.layer.maskedCorners = [.layerMaxXMaxYCorner]
    return v
}()

var searchBarView:UIView = {
    let v = UIView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.backgroundColor = .white
    v.layer.cornerRadius = 10
    return v
}()

var searchTextField: UITextField = {
    let fld = UITextField()
    fld.translatesAutoresizingMaskIntoConstraints = false
    fld.placeholder = "Search Movie here"
    fld.textColor = .black
    fld.backgroundColor = .white
    fld.layer.cornerRadius = 10
    return fld
}()

var searchIconImageView: UIImageView = {
    let v = UIImageView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.image = #imageLiteral(resourceName: "searchIcon")
    return v
}()

var movieChoiceLabel: UILabel = {
    let lbl = UILabel()
    lbl.translatesAutoresizingMaskIntoConstraints = false
    lbl.text = "Movies of your\nchoice"
    lbl.numberOfLines = 0
    lbl.font = UIFont.systemFont(ofSize: 32, weight: .bold)
    lbl.textColor = .white
    let attrbText = NSMutableAttributedString(string: lbl.text!)
    let range = (lbl.text! as NSString).range(of: "choice")
    attrbText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.white.cgColor, range: range)
    lbl.attributedText = attrbText
    lbl.isUserInteractionEnabled = true
    
    
    return lbl
}()

var profileImageView: UIImageView = {
    let v = UIImageView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.layer.cornerRadius = 25
    v.image = #imageLiteral(resourceName: "profileImage")
    v.clipsToBounds = true
    return v
}()

lazy var movieStatusCollectionView : UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    collectionView.backgroundColor = .navRedColor
    collectionView.delegate = self
    collectionView.dataSource = self
    return collectionView
}()

let collections = ["Latest", "Trending", "Upcoming"]
let collectionViewCellID = "cellID"

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .white
    self.navigationController?.navigationBar.isTranslucent = false
    self.navigationController?.changeStatusBarColor(color: .navRedColor)
    movieStatusCollectionView.register(BaseCollectionViewCell.self, forCellWithReuseIdentifier: collectionViewCellID)
    setupViews()
    movieChoiceLabel.addGestureRecognizer(UITapGestureRecognizer(target:self, action: #selector(tapLabel(gesture:))))
}

func setupViews() {
    
    //AddSubviews
    view.addSubview(containerView)
    containerView.addSubview(topView)
    topView.addSubview(searchBarView)
    topView.addSubview(searchTextField)
    searchBarView.addSubview(searchIconImageView)
    topView.addSubview(movieChoiceLabel)
    topView.addSubview(profileImageView)
    topView.addSubview(movieStatusCollectionView)
    
    //Constraints
    NSLayoutConstraint.activate([
        
        //ContainerView
        containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        containerView.topAnchor.constraint(equalTo: view.topAnchor),
        containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        
        //TopView
        topView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
        topView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
        topView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 0),
        topView.heightAnchor.constraint(equalToConstant: 256),
        
        //SearchBarView
        searchBarView.leadingAnchor.constraint(equalTo: topView.leadingAnchor, constant: 20),
        searchBarView.trailingAnchor.constraint(equalTo: topView.trailingAnchor, constant: -20),
        searchBarView.topAnchor.constraint(equalTo: topView.topAnchor),
        searchBarView.heightAnchor.constraint(equalToConstant: 46),
        
        //SearchIconImageView
        searchIconImageView.leadingAnchor.constraint(equalTo: searchBarView.leadingAnchor, constant: 20),
        searchIconImageView.centerYAnchor.constraint(equalTo: searchBarView.centerYAnchor),
        searchIconImageView.widthAnchor.constraint(equalToConstant: 24),
        searchIconImageView.heightAnchor.constraint(equalToConstant: 24),
        
        //SearchTextField
        searchTextField.leadingAnchor.constraint(equalTo: searchIconImageView.trailingAnchor, constant: 15),
        searchTextField.trailingAnchor.constraint(equalTo: searchBarView.trailingAnchor),
        searchTextField.topAnchor.constraint(equalTo: searchBarView.topAnchor),
        searchTextField.bottomAnchor.constraint(equalTo: searchBarView.bottomAnchor),
        
        //MovieChoiceLabel
        movieChoiceLabel.leadingAnchor.constraint(equalTo: searchBarView.leadingAnchor),
        movieChoiceLabel.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant: 50),
        movieChoiceLabel.topAnchor.constraint(equalTo: searchBarView.bottomAnchor, constant: 24),
        
        //ProfileImageView
        profileImageView.trailingAnchor.constraint(equalTo: searchBarView.trailingAnchor),
        profileImageView.topAnchor.constraint(equalTo: searchBarView.bottomAnchor, constant: 24),
        profileImageView.widthAnchor.constraint(equalToConstant: 50),
        profileImageView.heightAnchor.constraint(equalToConstant: 50),
        
        //MovieCollectionView
        movieStatusCollectionView.leadingAnchor.constraint(equalTo: topView.leadingAnchor, constant: 28),
        movieStatusCollectionView.trailingAnchor.constraint(equalTo: topView.trailingAnchor, constant: -28),
        movieStatusCollectionView.topAnchor.constraint(equalTo: movieChoiceLabel.bottomAnchor, constant: 24),
        movieStatusCollectionView.bottomAnchor.constraint(equalTo: topView.bottomAnchor, constant: -10),
        
    ])
    
}

extension BaseViewController:  UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionViewCellID, for: indexPath) as! BaseCollectionViewCell
    cell.headinLabel.text = collections[indexPath.item]
    if indexPath.item == 0 {
        cell.separatorLine.isHidden = false
    }
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 90, height: 30)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: (collectionView.frame.height / 2) , left: -2, bottom: 0, right: 12)
}

}

HomeViewController

import UIKit

class HomeViewController: BaseViewController {

var topTrendingLabel: UILabel = {
    let lbl = UILabel()
    lbl.translatesAutoresizingMaskIntoConstraints = false
    lbl.text = "Top Trendings"
    lbl.textColor = .black
    lbl.font = UIFont.systemFont(ofSize: 20, weight: .medium)
    return lbl
}()

lazy var collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let v = UICollectionView(frame: .zero, collectionViewLayout: layout)
    v.translatesAutoresizingMaskIntoConstraints = false
    v.delegate = self
    v.dataSource = self
    return v
}()

var topTrendings: [TrendingMovies] = {
    let movie1 = TrendingMovies(imageName: "badboys", movieName: "Bad Boys")
    let movie2 = TrendingMovies(imageName: "angrymen", movieName: "12 Angry Men")
    return [movie1, movie2]
}()

let collectionCellID = "cellID"

override func viewDidLoad() {
    super.viewDidLoad()
    self.collectionView.register(HomeCollectionViewCell.self, forCellWithReuseIdentifier: collectionCellID)
}

override func setupViews() {
    super.setupViews()
    
    containerView.addSubview(topTrendingLabel)
    containerView.addSubview(collectionView)
    
    NSLayoutConstraint.activate([
        
        //TopTrending
        topTrendingLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 20),
        topTrendingLabel.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 24),
        
        //CollectionView
        collectionView.leadingAnchor.constraint(equalTo: topTrendingLabel.leadingAnchor),
        collectionView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -20),
        collectionView.widthAnchor.constraint(equalToConstant: 170),
        collectionView.heightAnchor.constraint(equalToConstant: 220),
        
    ])
}

//CollectionView
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionCellID, for: indexPath) as! HomeCollectionViewCell
    cell.backgroundColor = .blue
    return cell
}

override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 170, height: 220)
}


}

Any Help would be greatly appreciated!

Upvotes: 3

Views: 155

Answers (1)

Amais Sheikh
Amais Sheikh

Reputation: 453

You will have to override the cellForItemAt method in your HomeViewController and then one way to make this work is to check your collectionView in cellforItemAt method i.e

if collectionView == HomeCollectionView
{
   //deque home collection view cell and return here
}
else
{
   // use: super.collectionView(collectionView, cellForItemAt: indexPath)
}

Upvotes: 1

Related Questions