I'm working on a collection view to prompt images and I run into an issue. When I try to set an image to my UIImageView (in my cell) It crashes saying NSInvalidArgument here is the log:
-[UICollectionViewCell img]: unrecognized selector sent to instance 0x7ff063f81170
2018-07-10 10:10:50.645635+0200 App[41377:5706851]
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UICollectionViewCell img]:
unrecognized selector sent to instance 0x7ff063f81170'
Here is the part of the code the error:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
cell.img.image = [UIImage imageNamed:#"test"];
return cell;
}
I'm a 100% sure that it is supposed to work because I used the same method for a UITableView and the images were displayed properly.
Thanks for your reply.
UPDATE:
here is a screen of my storyboard if it can help:
According to the error you posted:
-[UICollectionViewCell img]: unrecognized selector sent to instance 0x7ff063f81170
The reason is obvious that the cell instance dequeued from tableview doesn't have the method "img".
I guess maybe the reuseIdentifier is incorrect so that you got wrong class cell instance which does not implement "img" method.
check your reuse identifier and cast your cell to your class
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = (*CollectionViewCell)[collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
cell.img.image = [UIImage imageNamed:#"test"];
return cell;
}
Related
I am using Custom cell(friendListCell) in my app. when i run this into an IOS 8 and later it works but in IOS 7 it crash and show error like below. i could not find the error where it present,
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UILabel 0x17892a10> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key keyPath.'
Below the code,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
return cell;
}
Note:
I delete all the reference to this cell even though it shows error.
That error message means that you are setting a variable on a UILabel from inside the storyboard/xib file that doesn't exist.
You can change the code anyway you want and that won't fix the problem. The error is in your storyboard or xib file. Are you trying to set a variable called keyPath in your storyboard/xib file?
Try this one for creating Cell:
static NSString *CellIdentifier = #"cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
I am getting the following error when I press a button that opens a tableview:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier title - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
Here is the code in the view controller for the tableview and the method that's causing the problem:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
I researched the error and I tried removing the forIndexPath:indexPath so the code looked like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
return cell;
}
Now this caused a new error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:
now I did some logging to find out that cell == nil was true so I added a check for that as suggested by some earlier questions:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] init]
}
return cell;
}
Now this removed all errors but now when I open the tableview, the cells are empty when I want the ones that I created in the storyboard.
How do I fix this problem?
Here is what the View Controller looks like in the storyboard:
there are two cell recycle methods you can call on a UITable
View,
-(UITableViewCell *) dequeueReusableCellWithIdentifier:forIndexPath:
-(UITableViewCell *)dequeueReusableCellWithIdentifier:
its somewhat confusing, but they are quite different in how they are used. The one which takes a second argument (of type NSIndexPath) is dependant on you first having registered a class or xib file with the tableView, in order that the tableView can create a cell ad-hoc for you when there isn't one handy for recycling. This first method will always return a cell, so you can code your cellForRowAtIndexPath: much like you have.
the second method (which takes only one argument, the (NSString *)cellIdentifier can and will return nil when there is no cell handy for recycling. So when you use this one you should test the result for nil and create a cell in that case.
eg
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellId = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
}
//etc etc decorate your cell...
return cell;
}
In order to exploit your cell prototypes you will need to register a class or xib for each row/section, so that the table knows which cell to create. The recycling stuff only really works once enough cells have been created to fill the screen and you start scrolling. Good luck
If you are creating your prototype cells in a Storyboard you need to set the "Identifier" field for them to your "CellIdentifier" string. You can do this by selecting the cell and looking in the Attributes Inspector.
If you are creating a separate .xib file for your UITableViewCell you need to call this method on your UITableView in code somewhere:
registerNib:forCellReuseIdentifier:
If you are doing everything in code and just using a UITableViewCell subclass that knows how to layout itself then you need to call this method on your UITableView:
registerClass:forCellReuseIdentifier:
Here is a link to the reference docs
I'm trying to display a TableView of a list of songs in a user's library. I used the code from this tutorial (which uses a storyboard, but I would like to try it a different way and with just a subclass of UITableView).
I get the error:
*** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit/UIKit-2903.23/UITableView.m:5261
2014-05-07 20:28:55.722 Music App[9629:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
and an error Thread 1: SIGABRT on the line:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
This is my code:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
NSArray *songs = [songsQuery items];
return [songs count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
NSArray *songs = [songsQuery items];
MPMediaItem *rowItem = [songs objectAtIndex:indexPath.row];
cell.textLabel.text = [rowItem valueForProperty:MPMediaItemPropertyTitle];
cell.detailTextLabel.text = [rowItem valueForProperty:MPMediaItemPropertyArtist];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Table-view-background.png"]];
cell.textLabel.textColor = [UIColor colorWithRed:0.278 green:0.278 blue:0.278 alpha:1.0];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Table-view-selected-background.png"]];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
return cell;
}
The app loads and works fine, showing a blank table when I run it in the iPhone simulator on my Mac. it comes up with this error when I run it on my iPhone.
Any help would be much appreciated, thanks!
If you create the table view programmatically, and you're just using the default UITableViewCell, then you should register the class (in viewDidLoad is a good place). You can also do this for a custom class, but only if you create the cell (and its subviews) in code (use registerNib:forCellWithReuseIdentifier: if the cell is made in a xib file).
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
However, this will only give you a "Basic" table view cell with no detailTextLabel. To get that type of cell, you should use the shorter dequeue method, dequeueReusableCellWithIdentifier:, which doesn't throw an exception if it doesn't find a cell with that identifier, and then have an if (cell == nil) clause to create the cell,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
//Configure cell
return cell;
}
Please, if you're using a custom class for your cell check that you've already registered the nib for the cell to use in your table view, as follow:
[self.yourTableViewName registerNib:[UINib nibWithNibName:#"YourNibName" bundle:nil]
forCellWithReuseIdentifier:#"YourIdentifierForCell"];
Apart from that please check that your custom UITableViewCell subclass has the appropiate reuse identifier.
If you're not using a custom class, please follow this instructions from Apple Docs:
The data source, in its implementation of the tableView:cellForRowAtIndexPath: method, returns a configured cell object that the table view can use to draw a row. For performance reasons, the data source tries to reuse cells as much as possible. It first asks the table view for a specific reusable cell object by sending it a dequeueReusableCellWithIdentifier:
For complete information, please go to this link: Creating a Table View Programmatically.
I hope this helps!
The reason for the crash is that you are using
[tableView dequeueReusableCellWithIdentifier: forIndexPath:]
which will cause a crash unless you specify a cell or nib file to be used for the cell.
To avoid the crash, use the following line of code instead
[tableView dequeueReusableCellWithIdentifier:];
This line of code will return nil if there is not a cell that can be used.
You can see the difference within the docs which can be found here.
There is also a good answer to a Q&A that can be found here
I know this is a bit late to answer this question but here is what I was missing.
I was doing:
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
But I should be doing this:
let cell = self.tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
Notice: the self. added next to tableView.
I hope this saves you 24 hours.
if you use default UITableViewCell (not customize one) [tableView dequeueReusableCellWithIdentifier: forIndexPath:], you must registerClass or registerNib; (dequeReusableCellIdentifier:forIndexPath won’t return nil cell, if the cell is not there, then it will automately create a new tableViewCell with the default UITableViewCellStyelDefault!)
otherwise, you can use [tableView dequeueReusableCellWithIdentifier] without registerClass or registerNib
If you are using StoryBoard then select that tableviewcontroller->table->Cell, give that Cell a 'Identifier' in attribute inspector.
Make sure you use the same 'Identifier' in 'cellforrowatindexpath' method.
- (void)deleteCell
{
[self.collectionViewMenu performBatchUpdates:^{
[self.itemsArray removeObjectAtIndex:1];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
[self.collectionViewMenu deleteItemsAtIndexPaths:#[indexPath]];
} completion:^(BOOL finished) { }];
}
Please help to solve this problem, what am I doing wrong? I got this error after trying to delete an item in my collectionView.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: object cannot be nil (key: <_UICollectionViewItemKey: 0x8d705e0> Type = SV Kind = UICollectionElementKindSectionHeader IndexPath = <NSIndexPath: 0x8d6f4b0> {length = 2, path = 0 - 0})'
I solve the problem with remove the header and footer size delegates. the problem was in the fact that I do not return a header or footer.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
setObjectForKey: object cannot be nil means that the cell you are trying to delete is possibly already been deleted.
You should try to debug it and see when you call the delete what views at what index paths are actually in your collection view.
You probably need to implement:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
in your dataSource. This did the trick for me.
I just try to call collectionViewLayout.invalidateLayout() before performBatchUpdates. Then make sure the layout implementation are correctly and make sure that you are not returning negative height for cell. For more detail you can visit below GitHub link.
https://github.com/ra1028/DifferenceKit/issues/13
It helped me to fix the error.
So I have custom UITableViewCells (made with storyboard), and when I do not literally alloc, init the cells, the app crashes. However, since they are custom cells, I don't know how to alloc/init them.
This code crashes:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCells *cell = (TableViewCells *)[tableView dequeueReusableCellWithIdentifier:#"TableViewCellsID"];
return cell;
}
with this printed to the console:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
I understand this means its crashing because there is no cell allocated yet, however when I try to allocate it, I have to specify a cell style.
So, when I build the cell as follows, it doesn't crash:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCells *cell = (TableViewCells *)[tableView dequeueReusableCellWithIdentifier:#"TableViewCellsID"];
if (cell == nil)
cell = [[TableViewCells alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"TableViewCellsID"];
return cell;
}
The problem is the code that works (the second set), requires me to set a UITableViewStyle. And as far as I know, there is no UITableViewStyleCustom.
Any helps would be appreciated.
It crashes in first case because there is no cell to reuse, and you are calling dequeueReusableCellWithIdentifier.
EDIT -
For custom cell initialisation you can check following threads -
How to make custom TableViewCell with initWithStyle after 3.0
initWithFrame vs initWithStyle