OdieO
OdieO

Reputation: 7004

UITableViewCell setSelected:animated: not working

This is driving me crazy. I've looked here on S.O. for what I thought was a simple answer but couldn't find one.

In my custom UITableViewCell:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{   
    // Configure the view for the selected state
    if (selected) {        
        [self.languageLevelNameLabel setTextColor:[UIColor blackColor]];        
    }
    else {        
        [self.languageLevelNameLabel setTextColor:[UIColor colorMessageCountZero]];
    }

    [self setNeedsDisplay];
}

In tableView:cellForRowAtIndexPath: of the controller:

 if ([level integerValue] == indexPath.row) {

        [cell setSelected:YES];
    }

I've inserted break points and selected == YES is getting passed for the correct cell, and the if statement is being executed when it should be, but the text never gets set to blackColor.

Upvotes: 25

Views: 24700

Answers (4)

Fran Martin
Fran Martin

Reputation: 2369

If you want to set your cell as selected use the method selectRowAtIndexPath:animated:scrollPosition: like this in your cellForRowAtIndexPath method of your table view

Objective-C

[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];

swift 4

tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)

Upvotes: 56

Cherish
Cherish

Reputation: 1

There is no need to call cell's setSelected method.Apple hope that we set cell's selected status through two functions ,one is didSelectRowAtIndexPath ,the other is didDeselectRowAtIndexPath,they always occurr in pairs.To solve this problem,we just call two functions:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];

[self tableView:self.leftTableView didSelectRowAtIndexPath:indexPath];
[self.leftTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];

Upvotes: 0

Drew C
Drew C

Reputation: 6458

For the cell to appear selected, you have to call -setSelected:animated: from within -tableView:willDisplayCell:forRowAtIndexPath: like so:

Objective C:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (/* should be selected */) {
        [cell setSelected:YES animated:NO];
        [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];  // required, as noted below
    }
}

Swift 3:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if (/* should be selected */) {
        cell.setSelected(true, animated: false)
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)  // required, as noted below
    }
}

Calling -setSelected from anywhere else has no effect.

Why? After initializing or dequeueing a cell, but before displaying it, the table view calls a private method called -_configureCellForDisplay:forIndexPath: which, among other things, sets the cell's selected property to NO. The delegate's willDisplayCell:forRowAtIndexPath: gets called after this, letting you set anything needed for display.

Upvotes: 77

ArNo
ArNo

Reputation: 2648

Try

NSIndexPath* selectedCellIndexPath= [NSIndexPath indexPathForRow:number_row  inSection:0];
[self tableView:tableViewList didSelectRowAtIndexPath:selectedCellIndexPath];
[tableViewList selectRowAtIndexPath:selectedCellIndexPath animated:YES scrollPosition:UITableViewScrollPositionTop];

Upvotes: 0

Related Questions