let cell = tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MessageTableViewCell
let cell2 = tableView!.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as MessageTableViewCell
The first cell is recognized fine. The second, is not. I have a storyboard with the proper identifiers set for each prototype cell. The (dynamic) tableView has both cells on it, which should be fine from what I understand. This is the exact error I receive:
* Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'unable to dequeue a cell
with identifier Cell2 - must register a nib or a class for the
identifier or connect a prototype cell in a storyboard
This would make perfect sense if the identifier for that second prototype cell wasn't "Cell2", however it is.
Here is the code in the entire function, notice how I am not even returning cell 2, simply dequeuing it:
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MessageTableViewCell
let cell2 = tableView!.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as MessageTableViewCell
if UIApplication.sharedApplication().statusBarOrientation.isLandscape == true {
cell.messageLabel.preferredMaxLayoutWidth = cell.frame.size.width - 80
} else {
cell.messageLabel.preferredMaxLayoutWidth = cell.frame.size.width - 35
}
preferredWidth = cell.messageLabel.preferredMaxLayoutWidth
cell.messageLabel.text = friends[indexPath!.row]
cell.messageLabel.sizeToFit()
cell.messageLabel.setNeedsDisplay()
return cell
}
It crashes on that second line (inside the function).
Note: I am now using XCode 6 Beta 4.
I experienced this as well. Try this:
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
I created a new nib, recreated the cell in there, and inserted this code, which all in combination solved the problem.
var nibName = UINib(nibName: "MainTableViewCell", bundle:nil)
self.tableView.registerNib(nibName, forCellReuseIdentifier: "SecondCell")
Related
Searched here and there but I couldn't find anything that I haven't already tried to fix my issue, so going to ask it again.
I am trying to use a collection view with custom cells.
The main collection view is in the Main View Controller.
I'm using a generic cell named GenericHomeCollectionViewCell, then customize another collection view that it has. This cell doesn't have any issue with registering and dequeuing. (It might sound weird but I already have an application with this usage and it works without any problem, so I wanted to use the same method again.)
The crash happens when I try to register and dequeue cells inside that generic cell.
I have 4 different custom cells for use which are registered in awakeFromNib().
GenericHomeCollectionViewCell.swift
override func awakeFromNib() {
super.awakeFromNib()
newsCollectionView.register(UINib(nibName: "HeadlineNewsCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "HeadlineNewsCollectionViewCell")
newsCollectionView.register(UINib(nibName: "HomeAuthorCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "HomeAuthorCollectionViewCell")
newsCollectionView.register(UINib(nibName: "NewsListCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "NewsListCollectionViewCell")
newsCollectionView.register(UINib(nibName: "HomeDetailedNewCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "HomeDetailedNewCollectionViewCell")
newsCollectionView.delegate = self
newsCollectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if sectionType == .swipe {
let cell : HeadlineNewsCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "HeadlineNewsCollectionViewCell", for: indexPath) as! HeadlineNewsCollectionViewCell
cell.prepareCell(news: newsList[indexPath.row])
return cell
} else if sectionType == .homeAuthor {
let cell : HomeAuthorCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeAuthorCollectionViewCell", for: indexPath) as! HomeAuthorCollectionViewCell
cell.prepareCell(news: newsList[indexPath.row])
return cell
} else {
let cell : HeadlineNewsCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "HeadlineNewsCollectionViewCell", for: indexPath) as! HeadlineNewsCollectionViewCell
cell.prepareCell(news: newsList[indexPath.row])
return cell
}
}
When I launch the application, I get crash with error:
*** Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:], UICollectionView.m:6502
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier HeadlineNewsCollectionViewCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
I tried to give a reuse identifier name from the storyboard editor's but there is no difference.
I am using xib file to create a custom cell. The reuse identifier is set up in the xib file. Then I have a lazy var that I use to register the nib only once:
private lazy var registerNib: Bool = {
let nib = UINib(nibName: "CustomTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "Custom")
return true
}()
During Cell Creating I just used the lazy var and dequeue the cell from the table view, using the same reuse identifier that I have in the xib file:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let _ = self.registerNib
let cell = tableView.dequeueReusableCell(withIdentifier: "Custom") as! CustomCell
return cell
}
But the unwrapping fails and the app crashes.
tableView.dequeueReusableCell returns nil
for some reason....
There are two methods named dequeueReusableCell.
dequeueReusableCell(withIdentifier:)
dequeueReusableCell(withIdentifier:for:)
But the unwrapping fails and the app crashes. tableView.dequeueReusableCell returns nil for some reason....
You are using the first one and the doc clearly says
Return Value
A UITableViewCell object with the associated identifier or nil if no such object exists in the reusable-cell queue.
You may want to use the latter.
Change the line:
let cell = tableView.dequeueReusableCell(withIdentifier: "Custom") as! CustomCell
To:
let cell = tableView.dequeueReusableCell(withIdentifier: "Custom", for: indexPath) as! CustomCell
You need to register your nib object in viewDidLoad(): method like this
let nib = UINib(nibName: "CustomTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "Custom")
Also, did you set the cell reuse identifier in the storyboard?
I have two tableviews with two different custom tableview cells.. and am doing this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableview {
let cell = tableview.dequeueReusableCell(withIdentifier: "matchescell") as! MatchesTableViewCell
// ......
return cell
} else {
let cell = tableview.dequeueReusableCell(withIdentifier: "filtercell") as! FilterTableViewCell
// ......
return cell
}
}
and of course i have registered them both from storyboard...
but i keep getting this:
on this line:
let cell = tableview.dequeueReusableCell(withIdentifier: "filtercell") as! FilterTableViewCell
tried to register them like this:
tableview.register(MatchesTableViewCell.self, forCellReuseIdentifier: "matchescell")
filterdrop.register(FilterTableViewCell.self, forCellReuseIdentifier: "filtercell")
but still getting the same error!
What am doing wrong?!
The problem is that you typed "tableview" instead of "tableView" in your else part:
replace :
let cell = tableview.dequeueReusableCell(withIdentifier: "filtercell") as! FilterTableViewCell
with :
let cell = tableView.dequeueReusableCell(withIdentifier: "filtercell") as! FilterTableViewCell
It is crashing because your "tableview" doesn't have this cell registered.
Add the "filtercell" identifier in the storyboard or xib custom cell (FilterTableViewCell).
Possible cause:
You haven't registered the class or the nib of the cell to the proper tableview
You haven't set the identifier in the cellview in you nib/storyboard
You have inverted the tableview and their cell type
This because you either didn't register the cell
tableView.register(CustomCellClass.self, forCellReuseIdentifier: "CellID")
//
tableView.register(UINib(nibName: "CustomCellClass", bundle: nil), forCellReuseIdentifier: "CellID")
or you swapped the dequeuing line for the tables
Have a look into your Tableview controller in the Storyboard. You should have another indentier than called in:
let cell = tableview.dequeueReusableCell(withIdentifier: "filtercell") as! FilterTableViewCell
BTW, you should always use this newer function
dequeueReusableCell(withIdentifier:for:)
instead of
dequeueReusableCell(withIdentifier:)
See this post for details.
You can easily solve this problem just to check what tableview you use at that time.
you can try this code,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) {
if (tableview == (yourtableview 1)) {
let cell = yourtableview 1.dequeueReusableCell(withIdentifier: "yourtableview Cell 1") as? yourtableview Cell 1
// write your code for tableview 1
return cell
}
else
{
let cell = yourtableview 2.dequeueReusableCell(withIdentifier: "yourtableview Cell 2") as? yourtableview Cell 2
// write your code for tableview 2
return cell
}
}
I have currently have two UITableViews populated with contacts for the app. I have one for simply viewing them and editing/deleting and one for searching/picking contacts from a list. However, I'm getting a returned nil value when trying to use the same custom class cell for both UITableViews.
These are my two cellForRowAtIndexPath functions.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("SecondCell") as! ContactCell
let item = contacts[indexPath.row]
cell.meetupLabel?.text = item.fullName
return cell
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("FirstCell") as! ContactCell
let item = contacts[indexPath.row]
cell.label?.text = item.fullName
return cell
}
If the table did not have a cell named FirstCell or SecondCell, the dequeueReusableCellWithIdentifier(_:) method will return nil, and you will need to construct the cell yourself.
// no don't do this.
let cell: ContactCell
if let c = tableView.dequeueReusableCell(withIdentifier: "FirstCell") as? ContactCell {
cell = c
} else {
cell = ContactCell(style: .default, reuseIdentifier: "FirstCell")
}
You should use dequeueReusableCell(withIdentifier:for:), which was introduced in iOS 6, if you would like UIKit to construct the cell for you:
// swift 3
let cell = tableView.dequeueReusableCell(withIdentifier: "FirstCell",
for: indexPath) as! ContactCell
// swift 2
let cell = tableView.dequeueReusableCellWithIdentifier("FirstCell",
forIndexPath: indexPath) as! ContactCell
...
Also, check if you have given the correct reuse-identifiers to the cells correctly in the interface builder.
As you said you are getting nil, my quick guess is that you haven't registered the cell at some point, runs earlier than this cell event. Look at this thread on how to register cell.
I'm actually doing an app which loads contents to a UICollectionView as the user selects 1 it should create a UITableViewCell and add it to an UITableView on the right but I keep getting errors
In the ViewDidLoad I register the Nib (where cart #IBOutlet var cart: UITableView? and is connected to Storyboard)
cart!.registerNib(UINib(nibName: "cartCell", bundle: nil), forCellReuseIdentifier: "Cell")
When the cell is selected I add the object to an array and refresh the table
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if indexPath.row < serviceList.count {
let service:Service = serviceList[indexPath.row]
cartOrder.append(service)
dispatch_async(dispatch_get_main_queue()){
self.cart!.reloadData()
}
}
}
But when the table is filling its content I get an error at the declaration of cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! cartCell
let serv = cartOrder[indexPath.row]
cell.lblName.text = serv.name
cell.lblDescription.text = serv.description
cell.imgService.image = UIImage(named: "star")
return cell
}
The error Im getting is
2016-02-19 16:41:33.375 trackMyDevice_1.0[43188:5851609] ***
Terminating app due to uncaught exception 'NSUnknownKeyException',
reason: '[<NSObject 0x7fe645009320> setValue:forUndefinedKey:]:
this class is not key value coding-compliant for the key imgService.'
Any help is well appreciated
I register the Nib
So you have a nib called cartCell.xib, is that right? And that's what you are registering here:
cart!.registerNib(UINib(nibName: "cartCell", bundle: nil),
forCellReuseIdentifier: "Cell")
Later you load that nib to get a cell, by saying this:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
forIndexPath: indexPath) as! cartCell
Now, that line makes an explicit claim that the cell loaded from the nib will be a cartCell. But the problem is that the top-level object in that nib, cartCell.xib, is in fact not a cartCell. It isn't any kind of UITableViewCell. It is an NSObject! And thus, you crash with a complaint that this thing is an NSObject:
<NSObject 0x7fe645009320> ... this class is not key value coding-compliant for the key imgService