0

I have a tableview of custom cells. In each cell, I m adding an label as a subview and loading data in the label.I m adding gradient in my cellForRowAtIndexPath for each cell inside if block where we check whether the cell is nil or not. Its working fine. But, I have an additional requirement now and the problem starts here. I need to check for the values and apply gradient effect for a particular label in the cell. Here is my code.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
   static NSString *CellIdentifier = @"Cell";
   NSNumberFormatter *formatter = [NSNumberFormatter new];
   [formatter setNumberStyle:NSNumberFormatterDecimalStyle];

    HistoryCustomCell *cell = (HistoryCustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil)
        {
             cell = [[HistoryCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;

            CAGradientLayer *gradient = [CAGradientLayer layer];
            gradient.frame = CGRectMake(cell.frame.origin.x + 2, cell.frame.origin.y, tableView.frame.size.width - 3, 44.0);
            gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:228.0/255.0 green:228.0/255.0 blue:228.0/255.0 alpha:1] CGColor], (id)[[UIColor colorWithRed:254.0/255.0 green:254.0/255.0 blue:254.0/255.0 alpha:1]CGColor], nil];
            [cell.layer insertSublayer:gradient atIndex:0];

       }

        NSMutableDictionary *dictValue = [arrHistoryValues objectAtIndex:indexPath.row];            

           tempBestEverValue = [dictValue objectForKey:@"bestEverValue"];
           tempBestValue = [dictValue objectForKey:@"bestValue"];

            cell.cell1.text = [dictValue objectForKey:@"year"];

            NSString *janValue = [dictValue objectForKey:@"janValue"];
            if ([janValue isEqualToString:@"(null)"]) {
                janValue = @"";
                cell.cell2.text = [NSString stringWithFormat:@"%@",janValue];

            }
            else
            {
                janValue = [formatter stringFromNumber:[NSNumber numberWithInteger:[janValue intValue]]];
                cell.cell2.text = [NSString stringWithFormat:@"$%@",janValue];

            }

            if ([[dictValue objectForKey:@"janBest"] isEqualToString:[dictValue objectForKey:@"janValue"]])
            {
                cell.cell2.font = [UIFont boldSystemFontOfSize:12.0];
            }
             if ([[dictValue objectForKey:@"janValue"]intValue] == [tempBestEverValue intValue])

            {
                CAGradientLayer *gradient = [CAGradientLayer layer];
                gradient.frame = cell.cell2.frame;
                gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:165.0 green:239.0 blue:156.0 alpha:1.0] CGColor], (id)[[UIColor colorWithRed:140.0 green:203.0 blue:90.0 alpha:1.0] CGColor], nil];
                [cell.layer insertSublayer:gradient atIndex:1];
            }
            else if ([[dictValue objectForKey:@"janValue"]intValue] == [tempBestValue intValue])

            {
                CAGradientLayer *gradient = [CAGradientLayer layer];
                gradient.frame = cell.cell2.frame;
                gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:173.0 green:251.0 blue:173.0 alpha:1.0] CGColor], (id)[[UIColor colorWithRed:181.0 green:255.0 blue:181.0 alpha:1.0] CGColor], nil];
                [cell.layer insertSublayer:gradient atIndex:1];
            }



            NSString *febValue = [dictValue objectForKey:@"febValue"];
            if ([febValue isEqualToString:@"(null)"]) {
                febValue = @"";
                cell.cell3.text = [NSString stringWithFormat:@"%@",febValue];

            }
            else
            {
                febValue = [formatter stringFromNumber:[NSNumber numberWithInteger:[febValue intValue]]];
                cell.cell3.text = [NSString stringWithFormat:@"$%@",febValue];

            }

            if ([[dictValue objectForKey:@"febValue"]intValue] == [tempBestEverValue intValue])

            {
                CAGradientLayer *gradient = [CAGradientLayer layer];
                gradient.frame = cell.cell3.frame;
                gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:165.0/255.0 green:239.0/255.0 blue:156.0/255.0 alpha:1.0] CGColor], (id)[[UIColor colorWithRed:140.0/255.0 green:203.0/255.0 blue:90.0/255.0 alpha:1.0] CGColor], nil];
                [cell.layer insertSublayer:gradient atIndex:1];
            }
            else if ([[dictValue objectForKey:@"febValue"]intValue] == [tempBestValue intValue])

            {

                CAGradientLayer *gradient = [CAGradientLayer layer];
                gradient.frame = cell.cell3.frame;
                gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:173.0/255.0 green:251.0/255.0 blue:173.0/255.0 alpha:1.0] CGColor], (id)[[UIColor colorWithRed:181.0/255.0 green:255.0/255.0 blue:181.0/255.0 alpha:1.0] CGColor], nil];
                [cell.layer insertSublayer:gradient atIndex:1];
            }
            if ([[dictValue objectForKey:@"febBest"] isEqualToString:[dictValue objectForKey:@"febValue"]])
            {
                cell.cell3.font = [UIFont boldSystemFontOfSize:12.0];
            }

      return cell;
}

Now, the gradient is not applied properly when I reload the table. Its randomly picking up cells and applying gradient. How do I properly remove the gradient before I reload the table. Breaking my head for quite a few days. Please help.

nOOb iOS
  • 1,384
  • 2
  • 19
  • 37

2 Answers2

0

I think that you do not take into account how reusable cells work. At some point, you add a gradient layer to a given cell: [cell.layer insertSublayer:gradient atIndex:1];. If you scroll this cell out of the visible area, this cell is later reused for other rows, still containing the layer.

Try the following: Whenever you want to show a cell without a gradient background, ensure that the cell your method returns doesn't contain a gradient layer. Use two different cell identifiers for the two cases, e.g. @"CellIdentifier" and @"GradientCellIdentifier" and add the gradient layer only on initialization of the cell in the latter case.

Theo
  • 3,826
  • 30
  • 59
  • Here, I always wanted the gradient to be present for the cell. And upon that for some values I need apply someother gradient color. Thats the reason, I have set [cell.layer insertSublayer:gradient atIndex:0] for all the cells and [cell.layer insertSublayer:gradient atIndex:1] for particular column cell where I need to show different gradient color. – nOOb iOS Jun 11 '13 at 08:45
  • I m not actually reusing the cell rows, the tableview is added to a scrollview. So all cells will be visible all the time. – nOOb iOS Jun 11 '13 at 09:13
0

You already have a custom cell (HistoryCustomCell), use it a bit better.

Rather than add the gradient layer in the table delegate, add it in the custom class and make it publicly available. Now, in the delegate you can do:

cell.gradientLayer.opacity = 0;

When the gradient isn't required and :

cell.gradientLayer.opacity = 1;
cell.gradientLayercolors = ...;

When the gradient is required and you need to specify the colour.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • I always wanted to show gradient color for whole cell and upon that I need to show someother gradient color for specific values. – nOOb iOS Jun 11 '13 at 08:49
  • That's fine. The custom cell could have a gradient for the full background and another for a section of the background and make them both publicly available. The same process applies. – Wain Jun 11 '13 at 10:48