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"];
Related
This is my code in cellForItemAtIndexPath, where I want load cell of two collectionView. Here first one is loaded loaded perfectlly but second one is loaded properly.
} else if (collectionView == _collBanner) {
static NSString *cellIdentifier = #"bannerCell";
NSDictionary *dictBanner = [arrImages objectAtIndex:indexPath.row];
BannerCollectionViewCell *cell = (BannerCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[collectionView registerNib:[UINib nibWithNibName:#"BannerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:cellIdentifier];
[cell setupBannerCell:dictBanner];
return cell;
}
return nil;
}
And my sizeForItemAtIndexPath method is...
} else if (collectionView == _collBanner) {
return CGSizeMake(_collBanner.frame.size.width -5, _collBanner.frame.size.height -2);
} else
return CGSizeMake(0, 0);
}
This line must be in viewDidLoad
[_collBanner registerNib:[UINib nibWithNibName:#"BannerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:cellIdentifier];
The problem is in the order of following two lines:
BannerCollectionViewCell *cell = (BannerCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[collectionView registerNib:[UINib nibWithNibName:#"BannerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:cellIdentifier];
The first one asks for a cell of BannerCollectionViewCell type, but for the collectionView to be able to dequeue it, the BannerCollectionViewCell has to be registered in the collectionView. Only the second line registers the cell type to the collectionView.
First you have to register the BannerCollectionViewCell type to the collectionView:
[collectionView registerNib:[UINib nibWithNibName:#"BannerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:cellIdentifier];
And only then you can dequeue cells using:
BannerCollectionViewCell *cell = (BannerCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
However, it is enough to register the cell only once, therefore the best way is to register the cell in the viewDidLoad (move the following line from cellForItemAt to viewDidLoad):
[collectionView registerNib:[UINib nibWithNibName:#"BannerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:cellIdentifier];
i am using two different uicollectionview with different two different uicollectionviewcell and structure of cell is also different how to i register both cell class in one controller view .
[self.collectionView registerClass:[HCTabBarItemCell class]
forCellWithReuseIdentifier:[HCTabBarItemCell reuseIdentifier]];
In case if you load your custom UICollectionViewCell subclass from .xib file you should also register its nib:
[self.collectionView registerNib:[HCTabBarItemCell nibName]
forCellWithReuseIdentifier:[HCTabBarItemCell reuseIdentifier]];
where class methods nibName & reuseIdentifier are declared and implemented in your (base) custom cell class:
+ (NSString *)reuseIdentifier {
return NSStringFromClass([self class]);
}
+ (UINib *)nibName {
return [UINib nibWithNibName:NSStringFromClass([self class]) bundle:nil];
}
Then just get your custom cell in cellForRow method by reuseIdentifier:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
HCTabBarItemCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:[HCTabBarItemCell reuseIdentifier]
forIndexPath:indexPath];
return cell;
}
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];
}
i am trying to create collectionView but it creates error as:
use of undeclared identifier in collectionView.
- (UICollectionView *)collectionView:(UICollectionView *)collectionView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell =
[collectionView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UICollectionViewCell alloc] init];
[UICollectionView setBackgroundColor:[UIColor redColor]];
}
[self.view addSubview:__collectionView];
// Do any additional setup after loading the view, typically from a nib.
}
If you are not using prototypeCell in the storyboard. You could either register Cell/Xib with the collectionView. Do this in viewDidLoad
[self.collectionView registerClass:[UICollectionViewCell class]
forCellWithReuseIdentifier: #"MyIdentifier"];
Registe your nib in view Did load method...
UINib *cellNib = [UINib nibWithNibName:#"NibCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cvCell"];
now run your app...
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