Question

I have a program that I want to split the screen into two different sections (UISplitViewController is not applicable here because I already have a UINavigationController as the rootMenuController.

The problem is that I can't get my UITableView or my UICollectionView to use the registerClass method. For UITableView it's not a problem, but it's required for the UICollectionView. I ran the simulator to show what it looks like with the UICollectionView disconnected.

What am I doing wrong where it won't register the class for cell reuse identifier>

#import "SELMenuViewController.h"

@interface SELMenuViewController () <UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate>

@property (weak, nonatomic) IBOutlet UIButton *backButton;
@property (weak, nonatomic) IBOutlet UIButton *paymentButton;

@end

@implementation SELMenuViewController
- (IBAction)employeeSelect:(id)sender {
    [self.navigationController popViewControllerAnimated:YES];
    self.navigationController.navigationBarHidden = NO;
}

- (IBAction)paymentScreen:(id)sender {
    NSLog(@"payment screen");
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:    (NSInteger)section {
    return 1;
}

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"menuCell" forIndexPath:indexPath];

    cell.backgroundColor = [UIColor redColor];
    return cell;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [[UITableViewCell alloc] init];
    cell.textLabel.text = @"text";
    return cell;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.itemsOrdered = [[UITableView alloc] init];
        self.menuItems = [[UICollectionView alloc] initWithFrame:self.view.frame     collectionViewLayout:[[UICollectionViewFlowLayout alloc] init]];
    [self.menuItems registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"menuCell"];
    }
    return self;
}

Here is the error log...

2014-07-29 18:52:40.302 OlymPOS[2267:60b] * Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:], /SourceCache/UIKit_Sim/UIKit-2935.137/UICollectionView.m:3241 2014-07-29 18:52:40.306 OlymPOS[2267:60b] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier menuCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard' *** First throw call stack: ( 0 CoreFoundation 0x00000001019a5495 exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010170499e objc_exception_throw + 43 2 CoreFoundation 0x00000001019a531a +[NSException raise:format:arguments:] + 106 3 Foundation 0x00000001012a0f19 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 189 4 UIKit 0x000000010083e2b7 -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 1324 5 OlymPOS 0x0000000100013efe -[SELMenuViewController collectionView:cellForItemAtIndexPath:] + 110 6 UIKit 0x0000000100831cae -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 264 7 UIKit 0x000000010083330b -[UICollectionView _updateVisibleCellsNow:] + 3581 8 UIKit 0x0000000100836ae1 -[UICollectionView layoutSubviews] + 243 9 UIKit 0x0000000100311993 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 354 10 QuartzCore 0x0000000104475802 -[CALayer layoutSublayers] + 151 11 QuartzCore 0x000000010446a369 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 363 12 QuartzCore 0x000000010446a1ea _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24 13 QuartzCore 0x00000001043ddfb8 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 252 14 QuartzCore 0x00000001043df030 _ZN2CA11Transaction6commitEv + 394 15 QuartzCore 0x00000001043df69d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89 16 CoreFoundation 0x0000000101970dc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23 17 CoreFoundation 0x0000000101970d37 __CFRunLoopDoObservers + 391 18 CoreFoundation 0x0000000101950522 __CFRunLoopRun + 946 19 CoreFoundation 0x000000010194fd83 CFRunLoopRunSpecific + 467 20 GraphicsServices 0x0000000104002f04 GSEventRunModal + 161 21 UIKit 0x00000001002b1e33 UIApplicationMain + 1010 22 OlymPOS 0x000000010000f663 main + 115 23 libdyld.dylib 0x00000001025235fd start + 1 24 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

iOS Simulator Xib image

Was it helpful?

Solution

You create a collection view in init, register your class properly, and set it to your (presumably) outlet.

Then, the view will be loaded, which happens later than init, and this will create another collection view and assign it to the outlet. This collection view hasn't had a class registered, so it fails.

It's not clear why you are bothering making a collection view if there is one in your xib, unless it was a desperate workaround.

The right thing to do is register the class in viewDidLoad, by which point the collection view from the nib will exist.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top