0

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];

    }


}
user3926564
  • 105
  • 1
  • 1
  • 6
  • possible duplicate of [How to use Reusable Cells in uitableview for IOS](http://stackoverflow.com/questions/25257378/how-to-use-reusable-cells-in-uitableview-for-ios) – staticVoidMan Aug 12 '14 at 11:13

1 Answers1

0

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.

JoeFryer
  • 2,751
  • 1
  • 18
  • 23
  • thanks for your response. I added a mutable array of 1 and 0 to keep track of the data but am still running to the same issue ` `if ([array objectAtIndex:indexPath.row==0]) { [myButton setTitle:@"Like" forState:UIControlStateNormal]; } else{ [myButton setTitle:@"Unlike" forState:UIControlStateNormal]; } `not sure what you mean by dequeueReusableCellWithIdentifier:indexPath?`I tried but got an error – user3926564 Aug 10 '14 at 09:21
  • the above edits are updated in the original post. I also added `[array replaceObjectAtIndex:sender.tag withObject:[NSNumber numberWithInt:1]]; ` to update the array when button is tapped. Still same issue though – user3926564 Aug 10 '14 at 09:31
  • Where you are looking up the value in your `array`, it needs to be `if ([array objectAtIndex:indexPath.row] == 0)`. You might want to consider creating a `Recipe` class instead though, to encapsulate everything about a recipe (it could have a name/title, and a 'liked' property). – JoeFryer Aug 10 '14 at 10:38
  • You are also setting the button title on the button that you are not setting a frame for. I'd advise you to create your own `UITableViewCell` subclass (preferably with a `xib`). It'll make this a bit easier for you. – JoeFryer Aug 10 '14 at 10:40
  • What's your deployment target (iOS version) for your project? – JoeFryer Aug 10 '14 at 10:41