0

I know there are bunch of questions here related to this topic but i couldn't find any that matches my issue. I have subclass of UITableViewCell named "CustomTableViewCell".

The below mentioned code works fine however, i have check marks in my cell and i wanted to stop the reusability since the max number of cells will not exceed 25, hence it would no affect the performance, i guess after many searches, i found out that i have to either remove the tableView dequeueReusableCellWithIdentifier method or just change the identifier to nil, but unfortunately, i get empty cell when i i do that, and my app crashes what am i missing here?

This works fine BUT it reuses cell.

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

    static NSString *CellIdentifier = @"CustomCell";

    CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    ...
    ...
    ...
    ...

    return cell;
}

While instead, this code crashes:

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

    static NSString *CellIdentifier = @"CustomCell";

    CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:nil];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    ...
    ...
    return cell;
}
J. Steen
  • 15,470
  • 15
  • 56
  • 63
DevCali
  • 398
  • 6
  • 20
  • 2
    If you feel you need to avoid cell reuse, you are probably doing something wrong. But if you really don't want reuse for some reason, you can always create all 25 cells up front and store them in an array. Then simply return the cell for the indexPath.row from your array. You need to avoid the call to `dequeueReusableCellWithIdentifier`. – rmaddy May 14 '13 at 02:59
  • I resolved my issue following this example of code... http://stackoverflow.com/questions/6315269/tableview-cell-reuse-and-unwanted-checkmarks-this-is-killing-me – DevCali May 14 '13 at 19:53

3 Answers3

2

Implement prepareForReuse

I strongly recommend you to use the reuse pattern, in my opinion its just bad practice not to do it. I guess the real reason that you avoid to use the reuse pattern is that you see 'old' state in your custom cells when they are being reused.

To avoid this, you should implement/override the prepareForReuse method in your custom cell, in this method you set all your custom properties to their default state.

In the cellForRowAtIndexPath you just reuse the cells and set your custom properties to their values.

- (void)prepareForReuse() {
    [super prepareForReuse];

    //Set your custom properties to their default state
    self.custom1 = ...;
    self.custom2 = ...;
}
iTukker
  • 2,083
  • 2
  • 16
  • 16
  • I tried this method just now, the problem with this one is that i have checkmark in my cells, when i uncheck first few and scroll down and then up, the cells that i unchecked are marked checked again because of this method "default values" :( I'm new to programming, not sure if i'm missing anything here?? – DevCali May 14 '13 at 06:27
  • So lets say the default for your checkmark is 'set'. Then in the prepare for reuse you 'set' your checkmark. And in the cellForRowAtIndexPath you will have an 'if then else' where you either 'set' it or 'unset' it based on your state. – iTukker May 14 '13 at 06:34
0

Remove the who chunk of code which which deals with reusing cell. No need to check if cell is nil. Everytime, create a new instance of UITableViewCell.

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

    CustomTableViewCell *cell = [[CustomTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@""];

    //do a bunch of stuff to fill the cell.

    return cell;
}

This piece of code will create a new cell everytime.

Srikar Appalaraju
  • 71,928
  • 54
  • 216
  • 264
  • i tried your suggested approach, removed the code that deals with reusing cell, and removed the reuse ID from the cell in storyboard but for some reason, now i don't get any cell in my table view... – DevCali May 14 '13 at 03:35
  • Not sure what am i doing wrong here.. i checked numberOfRowsInSection delegate method, that is set currently.. – DevCali May 14 '13 at 03:36
  • this method should definitely work. Then it would mean that there is some problem in creating a new instance of `CustomTableViewCell`. It is not initializing a new cell. – Srikar Appalaraju May 14 '13 at 03:37
  • 1
    @SrikarAppal Could you tell me what happens if I scroll the table view number of times, I think this approach will create the cells each time the datasource `cellForRowAtIndexPath:` gets called, So if I scroll the tableview it will create the new cells. – Prasad Devadiga May 14 '13 at 03:50
  • yea, that's what seems like, the instance of CustomTableViewCell is not initializing, i tried to make a property instance of CustomTableVIewCell, that didn't work either... – DevCali May 14 '13 at 03:52
  • @prasaddevadiga yes this creates a new `cell` instance each time scroll happens. But since @Ahmad wanted to stop cell reusability I suggested this. – Srikar Appalaraju May 14 '13 at 03:53
  • @Ahmad now that you know what the problem is, fix it. If `CustomTableViewCell ` is properly created then the above piece of code will work... – Srikar Appalaraju May 14 '13 at 03:54
  • @SrikarAppal you are correct, my small doubt is can't we make use of indexPath as reuseIdentifier by somehow, so that we can stop recreation of unnecessary cells during scrolling. – Prasad Devadiga May 14 '13 at 04:00
  • @Ahmad, did you try the other answer ? – Thilina Chamath Hewagama May 14 '13 at 04:07
  • @ThilinaHewagama yes, i just did... same problem, empty tableViewCells... It's strange, if i use this one line of code CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; everything works fine except the reusable issue, if i remove this or change the cellIdentifier to nil, i get empty Cells!! – DevCali May 14 '13 at 04:23
0

You can do something like this,

1) @property (nonatomic, strong) NSMutableDictionary *cellArray;

2)in viewDidLoad,

self.cellArray = [[NSMutableDictionary alloc] init];

3)

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

    static NSString *CellIdentifier = @"CustomCell";

    CustomTableViewCell *cell = nil;
    id c = [self.cellArray objectForKey:[NSNumber numberWithInt:indexPath.row]];
    if(!c){
        cell = [[CustomTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    cell.textLabel.text = @"init part goes here";
    ...
    ...
    ...
    ...
        [self.cellArray setObject:cell forKey:[NSNumber numberWithInt:indexPath.row]];
    }else{
        cell = (CustomTableViewCell *) c;
    }

    return cell;
}
Thilina Chamath Hewagama
  • 9,039
  • 3
  • 32
  • 45