1

As I discussed in the question here, I tried to set the background color of a UITableView using CAGradientLayer. I am populating the UITableView with some values in NSMutableArray like this...

- (void)viewDidLoad
{
    // ....
    if (!navigationItems) {
        navigationItems = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", @"4", nil];
    }

}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:213.0f/255.0f green:91.0f/255.0f blue:92.0f/255.0f alpha:1.0f] CGColor][[UIColor colorWithRed:213.0f/255.0f green:0.0f blue:0.0f alpha:1.0f] CGColor], nil];
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.colors = colors;
    gradientLayer.frame = tableView.bounds;

    [tableView.layer insertSublayer:gradientLayer atIndex:0];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    cell.textLabel.text = [navigationItems objectAtIndex:indexPath.row];
    cell.textLabel.textColor = [UIColor blackColor];

    return cell;
}

What happens is that the cells being populated with the initial values appear to have been overlapped with the gradient color I set. No text/border appears in those cells (cells with values 1, 2, 3, 4 in this case). What am I doing wrong over here?

Community
  • 1
  • 1
vikmalhotra
  • 9,981
  • 20
  • 97
  • 137

2 Answers2

5

Setting a backgroundView to the tableView worked for me. Here's how I did it:

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = colors;
gradientLayer.frame = tableView.bounds;

//[tableView.layer insertSublayer:gradientLayer atIndex:0];

UIView *tableBackgroundView = [[UIView alloc] init];
[tableBackgroundView.layer insertSublayer:gradientLayer atIndex:0];
[self.tableView setBackgroundView:tableBackgroundView];
vikmalhotra
  • 9,981
  • 20
  • 97
  • 137
1

Watch out for insertSublayer method! You are inserting new layers every time a cell is recycled. So after a few iterations, you'll have bunch of layer inside cell.

To avoid this, run a simple loop every time like this:

for (CALayer *layer in [cell.barView.layer.sublayers reverseObjectEnumerator]) {
    if ([layer isKindOfClass:[CAGradientLayer class]]) {
        [layer removeFromSuperlayer];
        break;
    }
}
vikmalhotra
  • 9,981
  • 20
  • 97
  • 137
Borut Tomazin
  • 8,041
  • 11
  • 78
  • 91