简体   繁体   中英

How can I change the background color of a UITableViewCell dynamically?

I have a variable that is going to keep track of how many cells need to be colored. So if that variable is 3, then the top three cells backgroundcolor will change. How can I do this?

I know I need to update this in

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

But how can I ensure the top cells have a different background color based on my variable?

The indexPath parameter is your starting point. If coloredCells is an integer that holds the number of cells you are coloring, your method would include something like

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
    // fetch or create the cell, first
    UITableViewCell *cell = // ... 

    // then set it up
    if(indexPath.row < self.coloredCells) {
        cell.contentView.backgroundColor = [UIColor redColor];
    } else {
        cell.contentView.backgroundColor = [UIColor whiteColor];
    }

    // perform rest of cell setup
    // ...

    return cell;
}

Now, if you adjust the value of coloredCells , you'll need to inform the table view that some of its views have changed. The laziest way to do that is to reload the whole table:

// elsewhere...
self.coloredCells = 4;
[self.tableView reloadData];

Or you can take a little more effort to reload just the cells that have colored backgrounds:

self.coloredCells = newColoredCount;
NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:newColoredCount];
for(int i = 0; i < newColoredCount; i++) {
    [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
[self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];

You would test for the row number and change the color accordingly. In cellForRowAtIndexPath use:

 //having allocated or recycled a cell into myCell pointer above
 //test for row and assign background color like so

if (indexPath.row < 3) {
  myCell.contentView.backgroundColor = [UIColor greenColor];
 } else {
  myCell.contentView.backgroundColor = [UIColor redColor];
 }

 //continue configuring your cell

You can use the tableView:willDisplayCell:forRowAtIndexPath: of your UITableViewDelegate to change things like the background colour of the cell. Changes made in cellForRowAtIndexPath may be lost before the cell is actually displayed, so it's usually better to do it in this method.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if(indexPath.row < numberOfColoredRows) {
        cell.backgroundColor = [UIColor redColor];
    }
}

From the discussion of this method in the reference:

A table view sends this message to its delegate just before it uses cell to draw a row, thereby permitting the delegate to customize the cell object before it is displayed. This method gives the delegate a chance to override state-based properties set earlier by the table view, such as selection and background color. After the delegate returns, the table view sets only the alpha and frame properties, and then only when animating rows as they slide in or out.

No, you don't have to update the tableView:cellForRowRowAtIndexPath: delegate method. All you have to do is this:

[self.tableView cellForRowAtIndexPath:indexPath].backgroundColor = desiredUIColor;

Note that calling tableView:cellForRowAtIndexPath: from type id<UITableViewDataSource> is different from calling cellForRowAtIndexPath: from type UITableView . The former calls the delegate method (this should never be directly called) and the latter returns the current cell for an index path without recalculating the cell .

If you only have one section in your table view, the math to calculate the top n cells is easy. If your "variable that is going to keep track of how many cells need to be colored" is (NSUInteger)numberOfHighlightedCells , this is some simple loop code your could run:

NSUInteger i;

for (i = 0; i < numberOfHighlightedCells; i++) {
    [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]].backgroundColor = desiredUIColor;
}

However, if you have more than one section in your table, some very complicated calculating of index paths may be necessary.

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