Search code examples
objective-ccocoa-touchuitableviewuinavigationcontroller

Multi-View TableView with RootController


I am trying to create a multi-view app with navigation template. I want table on the bottom part of initial view, with other views (image view, labels, etc) on the top.

Originally I modified RootViewController.xib to resize tableview, and added image view, but nothing displayed except full-size table.

So I modified RootViewController.xib to add UIView, then added a UITableView and UIImageView to that view. I added IBOutlet for the tableView. In my RootViewController.xib, File'S Owner (RootViewController) has outlet connection to the view and the table view. When I right-click the UITableView, I see the referencing outlet to File's Owner. When I right-click the UIView, I see the referencing outlet to File's Owner. (I don't have an outlet to UIImageView, since I don't modify in code; do I need one?).

However, when I launch the app, it crashes with message:

'NSInternalInconsistencyException',
reason: '-[UITableViewController loadView] loaded the "RootViewController" nib but didn't get a UITableView.'

Here is the cellForRowAtIndexPath method:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *QuizIdentifier = @"QuizIdentifier";

    UITableViewCell *cell =
    [tableView dequeueReusableCellWithIdentifier:QuizIdentifier];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc]
                 initWithStyle:UITableViewCellStyleDefault
                 reuseIdentifier:QuizIdentifier]
                autorelease];
    }

    // Configure the cell.

    UIImage *_image = [UIImage imageNamed:@"icon"];
    cell.imageView.image = _image;

    NSInteger row = [indexPath row];
    cell.textLabel.text = [_categories objectAtIndex:row];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

Solution

  • You're getting that error because when you create a navigation-based iOS app, Xcode makes the RootViewController a subclass of UITableViewController. Once you combine that UITableView with a normal UIView, your subclass no longer complies with the UITableViewController class. So, in your RootViewController.m and .h files change UITableViewController to UIViewController. You may also need to change a few other things in your init method, but let's just start with this.

    Try this:

    - (UITableViewCell *)tableView:(UITableView *)tableView 
             cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        NSLog(@"\n\nI'm in Root / cellForRowAtIndexPath");
    
        static NSString *QuizIdentifier = @"QuizIdentifier";
    
        UITableViewCell *cell = 
        [tableView dequeueReusableCellWithIdentifier:QuizIdentifier];
    
        if (cell == nil) {
            cell = [[[UITableViewCell alloc]
                     initWithStyle:UITableViewCellStyleDefault
                     reuseIdentifier:QuizIdentifier]
                    autorelease];
            UIImage *_image = [UIImage imageNamed:@"icon"];
            cell.imageView.image = _image;
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
    
        // Configure the cell.
        NSInteger row = [indexPath row];
        cell.textLabel.text = [_categories objectAtIndex:row];
    
        NSLog(@"  We are at row %i with label %@ ", row, cell.textLabel.text);
    
        return cell;
    }