Search code examples
iosswiftuitableviewxib

Creating single .xib for different UITableViewCell classes


I am facing a problem.

I have a NNVerticalStackTableViewCell.xib file and its corresponding NNVerticalStackTableViewCell.swift file.

Code for NNVerticalStackTableViewCell.swift file:

class NNVerticalStackTableViewCell: UITableViewCell
{
    //MARK: Outlets
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var verticalStack: NNVerticalStackView!
    
    //MARK: Internal Properties
    var titleString : String?
        {
        set{
            self.titleLabel.text = newValue
        }
        get{
            return self.titleLabel.text
        }
    }
    
    //MARK: View Lifecycle Methods
    override func awakeFromNib()
    {
        super.awakeFromNib()
        self.titleLabel.text = nil
    }
    
    //MARK: Internal Methods
    func addViewsInVerticalStack(viewsArray : [UIView])
    {
        for view in viewsArray
        {
            self.verticalStack.insertStackItem(view)
        }
    }
}

Interface for NNVerticalStackTableViewCell.xib file

enter image description here

with class name as : NNVerticalStackTableViewCell and cell identifier as : NNVerticalStackTableViewCell

Now I created a subclass of NNVerticalStackTableViewCell as:

class NNPropertiesUnderProjectTableViewCell: NNVerticalStackTableViewCell
{
    //MARK: Internal Properties
    var completionHandler : ((NNSearchPreference) -> Void)?
    
    //MARK: Internal Methods
    func configureCell(_ propertiesUnderProjectArray : [[String : Any]])
    {
        var viewsArray = [UIView]()
        for dict in propertiesUnderProjectArray
        {
            let elementView = NNPropertiesUnderProjectElementView.loadFromNib()
            elementView?.configureViewWith(buttonTitleString: dict["displayString"] as! String, searchPreference: dict["searchPreference"] as! NNSearchPreference, completionHandler: {[weak self] (searchPreference) in
                if let handler = self?.completionHandler
                {
                    handler(searchPreference)
                }
                })
            viewsArray.addObject(elementView)
        }
        self.addViewsInVerticalStack(viewsArray: viewsArray)
    }
}

Now what I want to do is use NNPropertiesUnderProjectTableViewCell class with NNVerticalStackTableViewCell.xib interface.

Similar to NNPropertiesUnderProjectTableViewCell class I have many other classes that uses the same interface as NNVerticalStackTableViewCell.xib and customize it accordingly.

In my ViewController, I registered NNVerticalStackTableViewCell.xib and then creating the cell as:

self.tableView.register(UINib(nibName: "NNVerticalStackTableViewCell"), forCellReuseIdentifier: "NNVerticalStackTableViewCell")


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
            let propertiesUnderProjectCell = tableView.dequeueReusableCell(withIdentifier: "NNVerticalStackTableViewCell", for: indexPath as IndexPath) as! NNPropertiesUnderProjectTableViewCell
    }

But, I am getting the exception:

Could not cast value of type 'NNVerticalStackTableViewCell' (0x100945878) to 'NNPropertiesUnderProjectTableViewCell' (0x100949330).

How can I solve the problem? I want to use single .xib and do not want to repeat the code.


Solution

  • You can, but, instead of using the UITableViewCell, use similar UIView

    Create a xib for the cell content view, give it a class (like CellView). In each cell class, get the CellView with loadNibNamed and set it as the cell content view, then you can freely change the property of the CellView and use it as other cell class's content view

    Maybe there's better solution, but this is how i do it for similar looking UIViewController, you might also try cell xib without class set in storyboard and try to load it and see if the error still persist or not