I am no graphics expert but I somehow managed to make some good looking custom grouped UITableViewCells by setting the background view to a backgroundView with some CG code. In all SDK's up to 3.1.3 (maybe 3.2... I haven't tested on the iPad) this was working great, but I think a more recent SDK has introduced a change in the way graphics are cached offscreen.
Upon first render, everything is great: The drawing is fine and the corners are transparent. If I push a couple of view controllers on the navigation stack and come back, there are now black corners that appear in the views:
(source: tinygrab.com)
(source: tinygrab.com)
I have tons of code, most of which is written up here. I have tried tweaking to the best of my ability, looking at the docs for applicable changes, but after at least 8 hours in I still cannot find what might cause this. I have tried setting every view I can think of to be backgroundColor=clearColor
and opaque=NO
What else am I missing? Any debugging tips?
I have some debug code in viewDidAppear
that prints the backgroundColor and class description of all the subviews.
- (void)debugView:(UIView *)view {
DebugLog(@"%@ - %@", view.backgroundColor, [[view class] description]);
for (UIView* child in view.subviews) {
[self debugView:child];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[DownloadController.networkQueue setSuspended:NO];
for (TTTableViewCell *cell in [self.tableView visibleCells]) {
[cell debugView:cell];
}
}
With this code, I inspect the backgroundColor settings of the cell views on first load, when it is fine, and then again after coming back. There are some differences, but all the colors are still set to be clear. This leads me to believe the issue is underneath the UITableViewCell.
I have created a simple sample application to highlight the problem.
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:
In order to get rid of the black corners you can:
[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).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:
override
property that change the layer's colors.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With