birdcage
birdcage

Reputation: 2676

UIButton color changes after scrolling in UITableView

I have a tableview and I am setting its cells in xib. I have a button in it and when I click it, it changes button color from red to green. When I scroll tableview and come back to green button, it returns to red again. Here is my code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"ProgramCell";

    ProgramCell *cell = (ProgramCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ProgramCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    [cell.btnHatirlat addTarget:self action:@selector(remind:)
                          forControlEvents:UIControlEventTouchUpInside];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
    [cell.contentView setUserInteractionEnabled: NO]; 

    return cell;
}

- (void) remind:(UIButton *)sender {        
    UIButton *btnTemp = (UIButton *)sender;
    int iTag = btnTemp.tag;

    // I want to change image of sender
    [btnTemp setBackgroundColor:[UIColor greenColor]];

}

EDIT: I have added my solution as an answer. I hope it will help.

Upvotes: 0

Views: 1196

Answers (3)

birdcage
birdcage

Reputation: 2676

Here is my solution and I want to thank again to @Bernard Grabowski and @MobiDevCom. I have saved clicked button's section and row number and checked if it is clicked or not.

(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"ProgramCell";

    ProgramCell *cell = (ProgramCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ProgramCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    NSString* strTemp = [NSString stringWithFormat: @"%d/%d", indexPath.section, indexPath.row ];

    //To check clicked button at current section and row is clicked
    for (int i = 0; i < buttonClickedArray.count; i++) 
    {
        if([[self.buttonClickedArray objectAtIndex:i] isEqualToString:strTemp])
            [cell.btnHatirlat setBackgroundColor:[UIColor greenColor]];
    }


    NSString *str = [[etkinlikArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];


    [cell.btnHatirlat addTarget:self action:@selector(remind:)
               forControlEvents:UIControlEventTouchUpInside ];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
    [cell.contentView setUserInteractionEnabled: NO]; 
    }

    return cell;
}

- (void) remind:(UIButton *)sender
{
    //to get clicked button's indexpath
    UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
    NSIndexPath *clickedButtonPath = [self.tableProgram indexPathForCell:clickedCell];
    self.currentIndexPathStr = [NSString stringWithFormat: @"%d/%d", clickedButtonPath.section, clickedButtonPath.row];

    [self.buttonClickedArray addObject:currentIndexPathStr];

    [btnTemp setBackgroundColor:[UIColor greenColor]];

}

Upvotes: 0

LLIAJLbHOu
LLIAJLbHOu

Reputation: 1313

You need store pressed button's cell index.

Try this->

- (void)remind:(UIButton *)sender {        
    UIButton *btnTemp = (UIButton *)sender;
    self.iTag = btnTemp.tag;
    /*For many buttons
    [btnTemp setSelected:![btnTemp isSelected]];
    self.buttonStates[btnTemp.tag] = @([btnTemp isSelected);
    */

    // I want to change image of sender
    [btnTemp setBackgroundColor:[UIColor greenColor]];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"ProgramCell";

    ProgramCell *cell = (ProgramCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ProgramCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    if (self.iTag == indexPath.row) {
        [cell.btnHatirlat setBackgroundColor:[UIColor greenColor]];
    }
    /*For many buttons
    [cell.btnHatirlat setSelected:[self.buttonStates[indexPath.row] boolValue]];
    if ([cell.btnHatirlat isSelected]) {
        [cell.btnHatirlat setBackgroundColor:[UIColor greenColor]];
    }
    */

    [cell.btnHatirlat addTarget:self action:@selector(remind:)
                      forControlEvents:UIControlEventTouchUpInside];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
    [cell.contentView setUserInteractionEnabled: NO]; 

    return cell;
}

Good luck!

Upvotes: 1

Bernhard Grabowski
Bernhard Grabowski

Reputation: 469

I'd do this:

The Tableview doesn't know how to "remember" the button state when it reuses the cell.

I'd create a NSMutableArray which holds a BOOL (or any other) flag wether the button is "on" or "off". Init that Array with all "off" if you like and then change the value at the index corresponding with the indexPath.row accordingly on click to "on". Read the value in cellForRowAtIndexPath and change the color accordingly.

If you got multiple sections, create an Array for each section and let it hold an Array for the respective number of cells.

If that tableView is backed up by a DB add a flag for the state (on/off), and save it. Out of my head I don't know wether this requires a reloadData for everything to work as expected.

Upvotes: 1

Related Questions