Black Corners On Grouped UITableViewCells Only After Navigation Pops

I have tested the sample application and can reproduce the black corners issue.

After some experiments, it seems that the black corners issue is related to the caching of the layers used to render the table view. The geometry of the cell's layer seems to be important:

  • On the first paint, the cell is asked to be painted into a rect. Your code is painting a rounded path, but clipped out the corners. As the underlying tableview is already drawn, no problem occurs. The rect zone is cached, with its corners unpainted.
  • When the controller is pushed, a cached image is stored, with rectangular placeholders for the cells.
  • When the controller is popped, the cached image and the cells are drawn. But the place to draw cells is rectangular but the cell's cached image is not, leading to black corners.

In order to get rid of the black corners you can:

  • Make sure that all the cell's rect is painted. This means using the same color to file the cell before drawing the edge as the tableview's background color. If your tableview use the default background color, you can use [UIColor groupTableViewBackgroundColor].CGColor as filling color; it is a pattern based color and follows device orientation (yeah); but the painting is not perfectly aligned with the background (damn).
  • Use a CALayer mask on the cell's layer. This implies creating a mask CGImage, set it as the layer's content and assign the mask layer to the cell's layer. Not sure about the performance.

Hope it helps a bit.

Update

After some unsuccessful attempts, I dropped the mask idea because it was too clumsy.

I have re-read the code for the cell's layer and found out a way to remove the black corners in a simple way. The basic idea is that a CAGradientLayer is fully transparent only if its gradient colors are clear. By using the following display method, the black corners went away (both on the simulator and on the device):

- (void)display {
    if (_override) {
        self.colors =
        [NSArray arrayWithObjects:
         (id)[UIColor colorWithRed:colorComponents[0] green:colorComponents[1] blue:colorComponents[2] alpha:colorComponents[3]].CGColor,
         (id)[UIColor colorWithRed:colorComponents[4] green:colorComponents[5] blue:colorComponents[6] alpha:colorComponents[7]].CGColor,
         nil];
    } else {
        self.colors =
        [NSArray arrayWithObjects:
         (id)[UIColor clearColor].CGColor,
         (id)[UIColor clearColor].CGColor,
         nil];
    }
    [super display];
}

Of course, this could be optimized a bit:

  • Create the color arrays once.
  • Provide a custom setter for override property that change the layer's colors.
  • Remove the display method as it is no needed anymore.

I experimented with your sample code using OS3.2 on the simulator and it definitely shows the same symptom. I tried a few things and ended up with this fix:

self.cornerRadius = 12;

Add this into UAGradientCellBackgroundLayer, in init method.