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
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.
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
You can't do that as the registerNib:
expect the same instance of the exact registered view.
From here you can do is replicate NNVerticalStackTableViewCell.xib
and retain NNVerticalStackTableViewCell.swift
as your base class.
then create something like NNPropertiesUnderProjectTableViewCell.xib
where it holds the exact same view as before NNVerticalStackTableViewCell.xib
with your added controls. Then subclass it to NNPropertiesUnderProjectTableViewCell.swift
with a unique identifer: NNPropertiesUnderProjectTableViewCell
.
in which NNPropertiesUnderProjectTableViewCell
is a subclas of NNVerticalStackTableViewCell
.
From here, just add your additional controls unique to NNPropertiesUnderProjectTableViewCell
class.
You can Do like this if you want to use tableViewCell.xib in multiple Time. First Go to File and Create New File (Cocoa Touch Class).
Create TableViewCell File With .xib
Now Simple Create your Custom Cell Design
Now Add this code in your File TableViewCell.swift
Now just add identifier in your tableView Cell like this (where you want to add this custom TableviewCell)
Now just take it as your Cell Like this..
And Bingo You got it..
Now just add cell as! TableViewCell in any TableViewController File (You got same results with same Design.)
Here of Click First (Load First TableViewController)
On Click Second (Load Second TableViewController)
Basically, you can't do exactly what you're trying to do because the class name is in the XIB so you always get an instance of the base class, not any of your subclasses.
The suggestion from @Tj3n is a good one, extract the common part into a reusable view and in your superclass initialisation create an instance of that view and add it. Now, when you instantiate a subclass and it calls super the common element will be initialised and usable by the subclass.
In other words, use composition to achieve your goal, not inheritance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With