PGDev PGDev - 24 days ago 6
Swift Question

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).


Can anyone please suggest how to solve the problem. I want to use single
.xib
and do not want to repeat the code.

Answer

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