简体   繁体   中英

UiButton state keeps changing when scrolling in UITableview

I know there are a few posts abou this but I am still confused why the button i created in a tableview wont keep its state when its selected. When I scroll, unselected buttons get affected and it changes back and forth. Please help.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    static NSString *simpleTableIdentifier = @"SimpleTableCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
        UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [myButton setTitle:@"Like" forState:UIControlStateNormal];
        [myButton addTarget:self action:@selector(tapped:) forControlEvents:UIControlEventTouchUpInside];
        myButton.frame = CGRectMake(14.0, 10.0, 125.0, 25.0);
        myButton.tag =indexPath.row;
        [cell.contentView addSubview:myButton];



    }
    else{
        [cell.contentView addSubview:myButton];

    }
 if ([array objectAtIndex:indexPath.row==0]) {
        [myButton setTitle:@"Like" forState:UIControlStateNormal];

    }
    else{
        [myButton setTitle:@"Unlike" forState:UIControlStateNormal];


    }


    cell.textLabel.text = [recipes objectAtIndex:indexPath.row];

    return cell;
}


-(void)tapped:(UIButton *)sender {

    if ([sender.currentTitle isEqualToString:@"Like"]) {
        [sender setTitle:@"Unlike" forState:UIControlStateNormal];
[array replaceObjectAtIndex:sender.tag withObject:[NSNumber numberWithInt:1]];
    }
    else{
        [sender setTitle:@"Like" forState:UIControlStateNormal];

    }


}

To help you understand why this happens; every time a row's cell is shown on screen on your table view, your tableView:cellForRowAtIndexPath: method is called to retrieve the cell that will be shown. That is, when a cell is shown for the first time, this method gets called. Then, if this cell goes of screen, and then comes back on screen again, this method will be called again , to setup and retrieve the cell.

So, in your case here, you are showing a cell (which has a button on it) for Recipe A . The button is pressed, which changes it's state. When Recipe A goes off screen, and then comes back on screen, you get back a different cell (because of table cell re-use with dequeueReusableCellWithIdentifier: ). For the button on that cell, two things are going on:

  • There is already a button on the cell from the first time it was used (maybe for a different recipe). You don't tell it whether it should be in the 'liked' or 'unliked' state for Recipe A .
  • You add another button to the cell, but you don't actually set its frame/title, so you won't actually see it any way.

What you need to do is keep a track, in your model somewhere, of which of your items (recipes) the user has 'liked'. You'd do this somewhere in your tapped: method.

Then, in your tableView:cellForRowAtIndexPath: method, you need to set the button to the appropriate state ('liked' or not) for that row/recipe.

You need to make sure you do this every time the method is called, not just in your if (cell == nil) block. By the way, is there a reason you are using dequeueReusableCellWithIdentifier: instead of dequeueReusableCellWithIdentifier:indexPath ? The latter is available from iOS 6 onwards, and is guaranteed to return a cell, so you don't need to do this if (cell == nil) business.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM