Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView and its cell in a xib file

Long story short, I want to create a XIB file, where it contains:

  1. A view. In that view, it has many things and a tableView. (connected data source, delegate to file's owner). That view is the main view of the XIB files.

  2. Custom cell, (use as the prototype cell of tableView, since XIB doesn't support prototype tableView).

How could I achieve both of these? Also, I want to know the same apply to UICollectionView.

I had created both of those, load it to the main view (the main view is in the main storyboard). But the tableView doesn't load the custom cell as expected. The cell is just blank, doesn't look like what it's designed in the nib.

EDIT 1

Here's how I register the nib to the main view in storyboard:

- (UIView *)buildViewFromViewControllerClass:(Class)viewControllerClass
{
    id viewController = [[viewControllerClass alloc] initWithNibName:NSStringFromClass(viewControllerClass) bundle:nil];
    [viewController view].frame = self.containerView.bounds;

    [self addChildViewController:viewController];

    return [viewController view];
}

I have many viewControllers, so I figure out that this is the best way to add VC.

About the nib in description above, I just use regular initialization:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // init cell
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    if (!cell) {
        cell = [[PaymentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CustomCell"];
    }

    return cell;
}

If in the view did load method, I register the nib to the tableView, it'll crash in [tableView dequeueResuableCell...]. The registered code:

- (void)viewDidLoad
{
    [super viewDidLoad];

//    [self.tableView registerNib:[UINib nibWithNibName:self.nibName bundle:nil]
//                forCellReuseIdentifier:@"CustomCell"];
// I'm commenting it, because it caused crash.
}

Crash message:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key tableView.'

What did I do wrong here? Here's a picture how I designed the nib:

Model

As you can see, the file's owner's mainView is connected to the mainView, where it contain the tableView. The customCell is just a custom designed cell, define in the same file (the .m file).

like image 420
Eddie Avatar asked Jul 22 '15 08:07

Eddie


People also ask

Is it possible to add UITableView within a UITableViewCell?

yes it is possible, I added the UITableVIew within the UITableView cell .. :) no need to add tableview cell in xib file - just subclass the UITableviewCell and use the code below, a cell will be created programatically.

What is an XIB file?

What are XIB files? From the point of view of the UI designer, XIB files contain the views or windows that you design in Interface Builder – the controls, their layout and properties, and their connections to your code. It is important to understand that on a technical level, XIB files are stored object graphs.

How can we use a reusable cell in UITableView?

For performance reasons, a table view's data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView(_:cellForRowAt:) method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse.


1 Answers

You Should register the nib as follows.

[self.tableView registerNib:[UINib nibWithNibName:@"MyCell" bundle:nil] forCellReuseIdentifier:@"MyCell"]

I have generally seen that registerClass doesn't load the view, but only the class. I dont know why.

Also one .xib should contain only one view. So you have to make a different for UITableViewCell and UITableView. The reason behind is very simple. Each time the xib is loaded, all the view inside the xib are created. You wouldn't want a new table each time you create a cell. Right?

As for the crash you are facing. The error looks like there is an outlet issue with name tableView. Try removing outlets and re initializing them

Additions

for a UICollectionView you can register a class, it would load your view from xib.

 [self.collectinView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier]

Update

If you are using a storyboard, you can just add two prototype cells and that will add two cells within the tableview. You can add all views right there and give different class files to them. Would reduce the number of xib files you need to maintain and also you will not require to register your nibs. This could be a tutorial for it

like image 186
Ganesh Somani Avatar answered Oct 03 '22 06:10

Ganesh Somani