Jay Imerman
Jay Imerman

Reputation: 4600

How to set and dequeue custom UITableViewCell with dynamic reuse identifier?

Here's what I am trying to do ultimately. I want to display a menu of items in a UITableView, but dynamically, so that the type of item displayed determines the custom cell view loaded. For example, let's say the menu item type is 'switch', then it will load a nib named 'switch.xib' and the state will be on/off depending on that particular menu item's value. There may be 5 items that are "switch" type, but different values. So I want to use the same xib for each one, but 5 instances.

So, long way around to the question. When I load the cell view from the nib, I would think it would need unique reuse identifiers for the dequeue for when it scrolls back on the screen, right? (Unique for each instance, i.e. each menu item.) In the UITableViewCell in Interface Builder, I see where I can set a reuse identifier property, but I want to set it at run time for each instance of the switch. For example, Menu Item #1 is a switch, #2 is a text field, #3 is a switch, etc. So #1 and #3 both need unique cell ID's to dequeue.

Here's what my cellForRowAtIndexPath looks like:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Cells are unique; dequeue individual cells not generic cell formats
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row];

ITMenuItem *menuItem = [menu.menuItems objectAtIndex:indexPath.row];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    // Load cell view from nib
    NSString *cellNib = [NSString stringWithFormat:@"MenuCell_%@", menuItem.type];
    [[NSBundle mainBundle] loadNibNamed:cellNib owner:self options:nil];
    cell = myCell;
    self.myCell = nil;
}
// Display menu item contents in cell
UILabel *cellLabel = (UILabel *) [cell viewWithTag:1];
[cellLabel setText:menuItem.name];
if ([menuItem.type isEqualToString:@"switch"]) {
    UISwitch *cellSwitch = (UISwitch *) [cell viewWithTag:2];
    [cellSwitch setOn:[menuItem.value isEqualToString:@"YES"]];
}
else if ([menuItem.type isEqualToString:@"text"]) {
    UITextField *textField = (UITextField *) [cell viewWithTag:2];
    [textField setText:menuItem.value];
}

return cell;
}

Upvotes: 2

Views: 13852

Answers (4)

Cynichniy Bandera
Cynichniy Bandera

Reputation: 6103

Your custom cell from xib file can be loaded in a way like this. The xib file name is the same as the cell class name and the reuse id.

- (YourCell *)tableView:(UITableView *)_tableView getCellWithId:(NSString *)cellId
{
        YourCell *cell;

        /* Cell id and xib have the same name. */
        cell = [_tableView dequeueReusableCellWithIdentifier:cellId];
        if (cell == nil) {
                NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellId owner:self options:nil];
                cell = [nib objectAtIndex:0];
        }
        return cell;
}

Upvotes: 0

Canberk Ersoy
Canberk Ersoy

Reputation: 438

For my idea, if your types are not too much design each cell in different xib and swift file. Mainly for performance issues.

If not possible to dequeue, give them different identifier. You can register more than one identifier for tableview or collection view (one of our apps using 12 different cells this way.)

But handling IBActions will be little messy this way.

Upvotes: -1

Bhushan_pawar
Bhushan_pawar

Reputation: 157

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(cell == nil)
    {
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    TextFieldFormElement *item = [self.formItems objectAtIndex:indexPath.row];
    cell.labelField.text = item.label;
    return cell;
}

Upvotes: 0

Alejandro
Alejandro

Reputation: 3746

You can set the reuse identifier in the nib file. So for switch.xib you would use 'switch' as the reuse identifier. Then just change

NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row];

to

NSString *CellIdentifier = menuItem.type;

assuming that menuItem.type is 'switch'

Upvotes: 0

Related Questions