UICollectionView: Unrecognized selector sent to instance - ios

I am getting this error. *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UICollectionViewCell label]: unrecognized selector sent to instance 0x1eead660' I am using a nib file as my cell and trying to displays the cells correctly. I am guessing that I am not returning cells correctly, but I am not too sure. Any help will be appreciated.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
Cell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
NSMutableArray *data = [sections objectAtIndex:indexPath.section];
cell.label.text = [data objectAtIndex:indexPath.item];
return cell;
}

UICollectionViewCell doesn't have a property called label.
Perhaps you meant:
[self.collectionView registerClass:[Cell class] forCellWithReuseIdentifier:#"Cell"];
Assuming you subclassed UICollectionViewCell, added label, and called your subclass Cell.

Your nib file probably needs to be connected to your custom class ('Cell'?) somehow. That done, you'd call:
[self.collectionView registerClass:[Cell class] forCellWithReuseIdentifier:#"Cell"];
As it stands right now, you are getting a vanilla UICollectionViewCell object back from dequeue..., and when you try to use it as a Cell, you get problems.
BTW, generally, your registerClass code should not go in cellForItemAtIndexPath. It only needs to be called once per view, e.g.
static NSString *cellIdentifier = #"Cell";
#implementation YourCollectionViewController
// ...
- (void)viewDidLoad
{
[self.collectionView registerClass:[Cell class] forCellWithReuseIdentifier:#"Cell"];
}
// ...
#end

Related

Searchbar cause app to crash in my ios library

I'm working on an external dynamic cocoa library (dylib) that at some point provides a view with a tableview and a search bar.
I have this on the on create
- (void)viewDidLoad {
[super viewDidLoad];
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
UINib *nib = [UINib nibWithNibName:CONTACT_CELL bundle:frameworkBundle];
[[self tableView] registerNib:nib forCellReuseIdentifier:CONTACT_CELL];
[self readContacts];
}
and for my tablerow delegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:CONTACT_CELL];
if (cell == nil)
{
NSLog(#"Cell was empty!");
}
Contact *c = [contacts objectAtIndex:[indexPath row]];
[[cell labelName] setText: [c getName]];
[[cell labelPhone] setText: [c getPhone]];
return cell;
}
problem is that when i click on the searchbar the app chrashes because:
* Assertion failure in -[UISearchResultsTableView
_configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UITableView.m:7962
2016-02-19 17:07:00.404 HostApp[2233:20181] * Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason:
'UITableView (; layer = ; contentOffset: {0, 0}; contentSize: {414, 528}>)
failed to obtain a cell from its dataSource ()'
if I use
[tableView dequeueReusableCellWithIdentifier:CONTACT_CELL forIndexPath: indexPath];
* Assertion failure in -[UISearchResultsTableView dequeueReusableCellWithIdentifier:forIndexPath:],
/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UITableView.m:6564
2016-02-19 17:37:08.254 HostApp[2691:28849] * Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason: 'unable
to dequeue a cell with identifier ContactCell - must register a nib or
a class for the identifier or connect a prototype cell in a
storyboard'
You can't return nil in cellForRowAtIndexPath.
You can either use :
[tableView dequeueReusableCellWithIdentifier:CONTACT_CELL forIndexPath: indexPath];
Which always returns a cell, or manually alloc it :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:CONTACT_CELL];
if (cell == nil)
{
NSLog(#"Cell was empty!");
cell = [UITableViewCell alloc] initWithStyle:<#(UITableViewCellStyle)#> reuseIdentifier:<#(nullable NSString *)#>];
}
Contact *c = [contacts objectAtIndex:[indexPath row]];
[[cell labelName] setText: [c getName]];
[[cell labelPhone] setText: [c getPhone]];
return cell;
}
check
1.search bar delegate for what you return
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{}
2. check number of rows in section tableview deleage
Try like this
ItemCell is my nibName not an identifier
- (void)viewDidLoad
{
[super viewDidLoad];
UINib *nib = [UINib nibWithNibName:#"ItemCell" bundle:nil];
[[self tableView] registerNib:nib forCellReuseIdentifier:#"ItemCell"];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create an instance of ItemCell
PointsItemCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ItemCell"];
return cell;
}
The problem was I registered the nib for the "normal" tableView, but not for the searchdisplaycontroller's tableView.
Using this viewDidLoad will fix the problem.
- (void)viewDidLoad {
[super viewDidLoad];
NSBundle *frameworkBundle = [NSBundle bundleForClass:[self class]];
UINib *nib = [UINib nibWithNibName:CONTACT_CELL bundle:frameworkBundle];
[[self tableView] registerNib:nib forCellReuseIdentifier:CONTACT_CELL];
[self.searchDisplayController.searchResultsTableView registerNib:nib forCellReuseIdentifier:CONTACT_CELL];
[self readContacts];
}

UICollectionViewCell Only Updates After Scrolling

I've got an issue with my UICollectionView where my cells are always initiated blank/in a default state with no data.
The data only appears in the cells after scrolling them in and out of view.
Code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"EquipmentCell";
APInventoryCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
if (!cell) cell = [[APInventoryCollectionViewCell alloc] init];
//set cell data...
cell.label.text = [arrayOfStrings objectAtIndex:indexPath.row];
return cell;
}
Your problem is that you probably set the arrayOfStrings somewhere in the viewDidLoad method of your view controller, the problem with that is that the collectionview datasource calls are done before that.
What you should do in your viewDidLoad method just call [collectionview reloadData]; an you will be fine

Error using dequeueReusableCellWithReuseIdentifer

I have a collection view in a storyboard with 4 collection view cell prototypes with the following identifiers: "Cell", "NoAlbumSelectedCell", "NoPhotosCell" and "NoVideosCell".
This is the code I'm using to load the cells:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (self.noAlbumSelected) {
return [collectionView dequeueReusableCellWithReuseIdentifier:#"NoAlbumSelectedCell" forIndexPath:indexPath];
}
if ([self.medias count] == 0) {
if ([self.listType isEqualToString:#"photo"]) {
UICollectionViewCell *noPhotosCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"NoPhotosCell" forIndexPath:indexPath];
return noPhotosCell;
} else {
UICollectionViewCell *noVideosCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"NoVideosCell" forIndexPath:indexPath];
return noVideosCell;
}
}
MediaCollectionViewCell *cell = (MediaCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
[self configureCell:cell forItemAtIndexPath:indexPath];
return cell;
}
When I try to display the "NoPhotosCell" cell, I get the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier NoPhotosCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
I tried to do a clean and rebuild.
Did you add the following lines at the end of viewDidLoad in your viewController?
[self.collectionView registerClass:[MediaCollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"NoAlbumSelectedCell"];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"NoPhotosCell"];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"NoVideosCell"];
If you have subclasses UICollectionViewCell, then you should use [YourUICollectionViewSubClass class] in conjunction with the above lines.
You have write following code in viewdidload
// Do any additional setup after loading the view from its nib.
[self.collectionView registerClass:[CollectionViewImageCell class] forCellWithReuseIdentifier:#"Cell"];

UICollectionView with UIViewController As Data Source

I have an array of dictionary with the first key as an image. I'm using UIViewController as the data source.
#interface myViewController () {
NSMutableArray *textureArray1;
NSMutableDictionary *dict1;
UIImage *key1a; // UIImage
NSString *key1b; // texture name
}
I don't have trouble populating this dictionary array with a TableView control laid out in the UIViewController.
- (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];
}
UIImage *image = [[textureArray1 objectAtIndex:indexPath.row] objectForKey:key1a];
cell.textLabel.text = [[textureArray1 objectAtIndex:indexPath.row] objectForKey:key1b];
cell.imageView.image = image;
return cell;
}
I want to do something new. And I want to populate the same array of images with UICollectionView where, again, UIViewController is the data source. Unfortunately, many tutorials that I find on the Internet have UICollectionViewController as the data source. Anyway, I have the following lines of code.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor colorWithPatternImage:[[textureArray1 objectAtIndex:indexPath.row] objectForKey:key1b]];
return cell;
}
And the application crashes with an error that says "unrecognized selector sent to instance..." Well, I don't know how to use UICollectionView. So how do you use UICollectionView with UIViewController?
Thank you for your help.
P.S. The following is the error message.
2013-03-20 10:21:07.777 iPadapp[2023:c07] -[__NSCFString _tiledPatternColor]: unrecognized selector sent to instance 0xdeacdf0
2013-03-20 10:21:07.778 iPadapp[2023:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString _tiledPatternColor]: unrecognized selector sent to instance 0xdeacdf0'
You need to say that your UIViewController is a UICollectionViewDataSource and UICollectionViewDelegate in your header. See this answer
This is a simple example. Your viewController should be conformed to UICollectionViewDelegate and UICollectionViewDelegateFlowLayout
- (void)viewDidLoad
{
[super viewDidLoad];
// Create the collection view and add it as a sub view
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(120, 120);
layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
layout.minimumInteritemSpacing =10.0f;
layout.minimumLineSpacing = 10.0f;
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.collectionView.backgroundColor = [UIColor whiteColor];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cell"];
[self.view addSubview:self.collectionView];
}
// Implement the required data source methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 50;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId =#"cell";
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
return cell;
}

Create UICollectionViewCell subclass with xib [duplicate]

This question already has answers here:
Xcode - How to fix 'NSUnknownKeyException', reason: … this class is not key value coding-compliant for the key X" error?
(79 answers)
Closed 7 years ago.
I'm trying to create a UICollectionViewCell subclass with linked a xib, I have do this:
I have create a new xib file and I have add a UICollectionViewCell in it, then I have create this subclass file:
#interface MyCell : UICollectionViewCell
#property (weak, nonatomic) IBOutlet UILabel *label;
#end
Also I have linked in the file owner custom class the MyCell class in interface builder, and I have added a UILabel, then in my UICollectionView viewDidLoad I do this:
[self.collectionView registerClass:[MyCell class] forCellWithReuseIdentifier:#"MyCell"];
UINib *cellNib = [UINib nibWithNibName:#"MyCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"MyCell"];
As well as in this:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = (MyCell*)[cv dequeueReusableCellWithReuseIdentifier:#"MyCell" forIndexPath:indexPath];
cell.label.text = #"Cell Text";
return cell;
}
However this doesn't work, I receive this error:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x907eca0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key label.'
What did I do wrong? How can I connect a UICollectionViewCell subclass to a xib, and display it in a UICollectionView?
EDIT:
i have do this:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = #"MyCell";
static BOOL nibMyCellloaded = NO;
if(!nibMyCellloaded)
{
UINib *nib = [UINib nibWithNibName:#"MyCell" bundle: nil];
[cv registerNib:nib forCellWithReuseIdentifier:identifier];
nibMyCellloaded = YES;
}
MyCell *cell = (MyCell*)[cv dequeueReusableCellWithReuseIdentifier:#"MyCell" forIndexPath:indexPath];
cell.labelCell.text = #"Text";
return cell;
}
Make sure the cell on the .xib file know what's the type of the cell.
Select the cell on your interface builder
and then on the identity inspector
Subsequently associate your labels with your properties. (I think you already did that)
Then I'd recommend to verify if you already loaded the .xib file on your cellForItemAtIndexPath: method
NSString *identifier = #"MyCell";
static BOOL nibMyCellloaded = NO;
if(!nibMyCellloaded)
{
UINib *nib = [UINib nibWithNibName:#"MyCell" bundle: nil];
[cv registerNib:nib forCellWithReuseIdentifier:identifier];
nibMyCellloaded = YES;
}
You can find the answer in this document UICollectionView adding UICollectionCell.
Only UICollectionView inside StoryBoard have UICollectionViewCell inside. If use XIB, create a new XIB with CellName.xib, add CollectionViewCell to it, specify name of UICollectionView custom class. After that use registerNib.Sample code: https://github.com/lequysang/TestCollectionViewWithXIB

Resources