iOS: how to dequeue reusable 'default' cells without actually having a cell in storyboard

46,503

Solution 1

If you don't have any prototype cell in your storyboard, you can use the dequeueReusableCellWithIdentifier: api to create classic cell

UITableViewCell *cell =  [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
   cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}

swift:

var cell : UITableViewCell!
cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
if cell == nil {
    cell = UITableViewCell(style: .default, reuseIdentifier: cellIdentifier)
}

Solution 2

Swift 3.0

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UITableViewCell = {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") else {
        return UITableViewCell(style: .default, reuseIdentifier: "cell")
        }
        return cell
    }()
    
    cell.textLabel?.text = anyArray[indexPath.row]
    
    return cell
}

It is good, because give cell unwrapped.

Solution 3

You can dequeue a UITableViewCell without having a prototype cell in your storyboard. You need to register the cell with your table for a specific identifier (string). You would do this like so:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:MyCellIdentifier];

You could do this in viewDidLoad, maybe.

Then, you can dequeue a cell using that identifier in your cellForRowAtIndexPath method as usual.

Edit:

Where MyCellIdentifier is a constant you have defined somewhere, of course.

Solution 4

You need to try to dequeue the cell, and if you get nil than create it. In the cell xib file define it's identifier.

Set the cell identifier in the nib file:

Set cell identifier

Get a reusable cell or make a new one:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"myCell";
    MyCell *cell = (MyCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        NSArray *t = [[NSBundle mainBundle] loadNibNamed:@"myCellXibFileName" owner:nil options:nil];
        for (id currentObject in t)
        {
            if ([currentObject isKindOfClass:[MyCell class]])
            {
                cell = (MyCell *)currentObject;
                break;
            }
        }
    }
    // Do whatever you want with the cell....
    return cell;
}
Share:
46,503
OMGPOP
Author by

OMGPOP

Gamer & Game Developer

Updated on April 03, 2021

Comments

  • OMGPOP
    OMGPOP about 3 years

    I have several tables the default cells such as the one with title, or the one with icon on the left and title on the right.

    I don't want to add those cells in storyboard and assign identifier to them, is it possible to do that?

    it has to be reusable, I know how to alloc new non-reusable cells

    I have tried the answers below,

    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:MyCellIdentifier];
    

    should be correct, but it's very tedious and easily forget

    UITableViewCell *cell =  [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
       cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    

    The above maybe better since it puts all the codes at one place, but when I try dequeueReusableCellWithIdentifier:forIndexPath: (with indexPath) it crashes.

    1. why does dequeueReusableCellWithIdentifier:forIndexPath crashes while dequeueReusableCellWithIdentifier does not?
    2. if i don't pass in indexPath, is the cell reusable
    3. if it is reusable, then whats the use of dequeueReusableCellWithIdentifier:forIndexPath?
  • OMGPOP
    OMGPOP about 10 years
    so only for the first time it's allocated, then all the rest are dequeued?
  • OMGPOP
    OMGPOP about 10 years
    r u sure u don't need to registerClass?
  • OMGPOP
    OMGPOP about 10 years
    the whole idea of this question is not to have a cell in xib or storyboard
  • Florian Burel
    Florian Burel about 10 years
    You don't need to register class if you use the dequeueReusableCellWithIdentifier: method. However you DO need to register if you use dequeueReusableCellWithIdentifier:forIndexPath: Both methods will give you a reusable cell, but the former method will instantiate it for you, so you need to have a registered class or a prototype cell. The first method will fetch a cell with the given identifier in the reuse stack and return nil if none is present, you then have to instantiate the cell yourself
  • JoeFryer
    JoeFryer about 10 years
    I wouldn't call registering UITableViewCell for an identifier very tedious, it is only one line of code :)
  • Aviel Gross
    Aviel Gross about 10 years
    Your question said nothing about xib, only storyBoard, and since storyBoard is managing cells different than xib (By letting you only call dequeueReusableCellWithIdentifier and always get a cell) I understood from your question that you seek to use xib file for your cell instead of putting it inside the tableView in your storyboard. Please be more clear next time.
  • user28434'mstep
    user28434'mstep almost 3 years
    This code skips reuse from the the cell pool completely.
  • CyberMew
    CyberMew over 2 years
    Does this add the created cell back into the pool for reuse later?
  • CyberMew
    CyberMew over 2 years
    Update: seems like it does in my testing. Which means when creating the cell with identifier, it is stored in the pool and taken to be used later. Thanks!