MissCoder87
MissCoder87

Reputation: 2669

UITableViewCell is being reused but I can't work out why?

I've got a tableview loaded from an array and for some reason it's re-using the cell but loading the same information lower down the table, a second time.

http://screencast.com/t/Ig8bcqSpLzp

The video above should give you an idea of what I mean.

This is my code to load the cell:

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
        accessicon *current =[arryAccess objectAtIndex:indexPath.row] ;
        cell.textLabel.text = current.text;
        cell.imageView.image = [UIImage imageNamed: current.iconPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        mySwitch *switchView = [[mySwitch alloc] initWithFrame:CGRectZero];
        cell.accessoryView = switchView;
        switchView.myValue = current.iconValue;

        if(totalIconValue & current.iconValue) {
            [switchView setOn: YES animated:NO];
        } else {
            [switchView setOn: NO animated:NO];

        }

        [switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
        [switchView release];


        return cell;


}

Any help will be appreciated

EDIT: I've updated my code above, however on the actual device it's still selecting items it shouldn't be - no longer reusing the names but if i scroll up and down it selects them on it's own?

see the video here: http://screencast.com/t/a9N1qbws

Tom

Upvotes: 0

Views: 361

Answers (3)

Sr.Richie
Sr.Richie

Reputation: 5740

You are constantly creating new rows instead of reusing the old ones.

Move the line

    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

inside the if block, end move everything else you have in the if block outside of it, except the lines

mySwitch *switchView = [[mySwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchView;

You need to create the switch only once for row, when it is initialized (that means, in the if statement). I suggest you to create it and assign it a tag, so you can access it later by its tag. Your code now is creating a new switch everytime the cell is used, this could be the reason why the switches are behaving this way.

Upvotes: 1

Mark Granoff
Mark Granoff

Reputation: 16938

This code:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
if (cell == nil) {
    ...

is fundamentally wrong. It should read:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    ...

And then, anything that is row-specific should be outside that if statement.

The pattern for this, generally, should be:

  • dequeue a reusable cell
  • if you didn't get one:
    • allocate a new cell
    • perform generic cell setup, i.e. setup that applies to all cells
  • setup the cell for the specific row, and return it.

Hope this helps.

Upvotes: 3

dasdom
dasdom

Reputation: 14073

You aren't reusing you cells. And you are filling the cells only when the init fails. Try this code:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}

accessicon *current =[arryAccess objectAtIndex:indexPath.row] ;
cell.textLabel.text = current.text;
cell.imageView.image = [UIImage imageNamed: current.iconPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
mySwitch *switchView = [[mySwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchView;
switchView.myValue = current.iconValue;

if(totalIconValue & current.iconValue) {
    [switchView setOn: YES animated:YES];
} else {
    [switchView setOn: NO animated:YES];

}

[switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[switchView release];

Or develop under ios5 and get rid of the alloc and init.

Upvotes: 2

Related Questions