I have used the following code in viewDidLoad
to register nib cell :
tableView.register(UINib(nibName: "ShoppingViewCell", bundle: Bundle.main), forCellReuseIdentifier: "ShoppingViewCell")
And in cellForRowAtIndexPath
I use the following for cell:
let cell = self.tableView.dequeueReusableCell(withIdentifier: "ShoppingViewCell", for: indexPath) as! ShoppingViewCell
return cell
But Sadly this only works with IOS 9 and up, trying to run this code on iOS 8.3 crashes with following error :
2016-09-27 14:17:04.859 Tazaj[29070:1917376] *** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-3347.44/UITableView.m:6245
2016-09-27 14:17:04.877 Tazaj[29070:1917376] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier ShoppingViewCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
Since register nib and dequeueReusableCell is already found since iOS 5/6, why its not working on iOS 8.3.
I know that by running the following code in cellForRowAtIndex
will solve the issue :
var mycell = tableView.dequeueReusableCell(withIdentifier: "ShoppingViewCell") as? ShoppingViewCell
if (mycell == nil) {
mycell = Bundle.main.loadNibNamed("ShoppingViewCell", owner: nil, options: nil)?.last as? ShoppingViewCell
}
But I have builded a whole project without check that cell is nil or not. I mean how can I solve the issue ? since apple said register cell and use the cell the way you want, I did it. so why only in iOS 8.x/8.3 it cannot work ?
How is it possible to ignore/fix that error with least replacing chunks of code in each cellForRowAtIndexPath
?
Just put this method in your custom cell class
class func cellForTableView(tableView: UITableView, atIndexPath indexPath: NSIndexPath) -> ShoppingViewCell {
let kShoppingViewCellIdentifier = "kShoppingViewCellIdentifier"
tableView.registerNib(UINib(nibName: "ShoppingViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier: kShoppingViewCellIdentifier)
let cell = tableView.dequeueReusableCellWithIdentifier(kShoppingViewCellIdentifier, forIndexPath: indexPath) as! ShoppingViewCell
return cell
}
And use it lieke below in your cellForRowAtIndexPath
let cell = ShoppingViewCell.cellForTableView(tableView, atIndexPath: indexPath)
// do something with your cell
I hope it helps.
Update for Swift 3 and Swift 4
class func cellForTableView(tableView: UITableView, atIndexPath indexPath: IndexPath) -> YourCustomTableViewCell {
let kYourCustomTableViewCellIdentifier = "kYourCustomTableViewCellIdentifier"
tableView.register(UINib(nibName: "YourCustomTableViewCell", bundle: Bundle.main), forCellReuseIdentifier: kYourCustomTableViewCellIdentifier)
let cell = tableView.dequeueReusableCell(withIdentifier: kYourCustomTableViewCellIdentifier, for: indexPath) as! YourCustomTableViewCell
return cell
}