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
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?
In viewDidLoad I register the cell like this:
let cellIdentifier = "Cell"
override func viewDidLoad() {
super.viewDidLoad()
let cellNib = UINib(nibName: "ViewCell", bundle: nil)
collection.register(cellNib, forCellWithReuseIdentifier: cellIdentifier)
}
and in cellForItemAt of the UICollectionViewDataSource I do:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// It crashes while trying to dequeue with the Error message: Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:]
let dequedCell = collection.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
return dequedCell
}
The onlystrange thing might be that the code is Mixed Swift/ObjC, and ViewCell is ObjC and gets imported in the bridging header:
#import "ViewCell.h"
I am getting the following error:
*** Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:],
/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UICollectionView.m:5106
I made sure all names are correct. Does anyone know why this crash is happening??
Here is problem
1) You need to register cell identifier in XIB,
2) Assign Class name to XIB
3) cell for row you need to check with as? YourClass in dequeue and
4) dequeue with same identifier you assign to XIB and register
Set collectionview cell identifier as Cell in storyboard.
Does anyone know why this crash is happening?
One thing to consider is that the docs for register(_:forCellWithReuseIdentifier:) say:
The nib file must contain only one top-level object and that object must be of the type UICollectionViewCell.
So, check that that's true. In other words...
let nibObjects = cellNib.instantiate(withOwner: nib, options: nil)
let count = nibObjects.count // is this 1?
let view = nibObjects.first // is view a UICollectionViewCell?
I am building a collection view and am getting the following error.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[appname.ViewsVC collectionView:cellForItemAtIndexPath:]: unrecognized selector sent to instance
Here is the code where i custom cell
// cell configuration
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ViewsCell", for: indexPath) as! ViewsCell
cell.fullnameLbl.text = self.viewsArray[(indexPath as NSIndexPath).row].capitalizeEachWord
// pic setup
avaArray[indexPath.row].getDataInBackground { (data:Data?, error:Error?) in
if error == nil {
cell.avaImg.image = UIImage(data: data!)
}
}
return cell
}
I created the collection view and the cell in storyboard and have given them the proper identifiers. I also connected the UIimageView and the label to the cell class.
Any ideas what could be wrong.
I realized that I was missing UICollectionViewDataSource and UICollectionViewDelegate at the top of the View controller
class ViewsVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
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")