The cell highlighting process can seem complex and confusing if you don't know whats going on. I was thoroughly confused and did some extensive experimentation. Here's the notes on my findings that may help somebody (if anyone has anything to add to this or refute then please comment and I will endeavour to confirm and update)
In the normal “not selected” state
- The contentView (whats in your XIB unless you coded it otherwise) is drawn normally
- The
selectedBackgroundView
is HIDDEN
- The
backgroundView
is visible (so provided your contentView is transparent you see the backgroundView
or (if you have not defined a backgroundView
you'll see the background colour of the UITableView
itself)
A cell is selected, the following occurs immediately with-OUT any animation:
- All views/subviews within the contentView have their
backgroundColor
cleared (or set to transparent), label etc text color's change to their selected colour
- The
selectedBackgroundView
becomes visible (this view is always the full size of the cell (a custom frame is ignored, use a subview if you need to). Also note the backgroundColor
of subViews
are not displayed for some reason, perhaps they're set transparent like the contentView
). If you didn't define a selectedBackgroundView
then Cocoa will create/insert the blue (or gray) gradient background and display this for you)
- The
backgroundView
is unchanged
When the cell is deselected, an animation to remove the highlighting starts:
- The
selectedBackgroundView
alpha property is animated from 1.0 (fully opaque) to 0.0 (fully transparent).
- The
backgroundView
is again unchanged (so the animation looks like a crossfade between selectedBackgroundView
and backgroundView
)
- ONLY ONCE the animation has finished does the
contentView
get redrawn in the "not-selected" state and its subview backgroundColor
's become visible again (this can cause your animation to look horrible so it is advisable that you don't use UIView.backgroundColor
in your contentView
)
CONCLUSIONS:
If you need a backgroundColor
to persist through out the highlight animation, don't use the backgroundColor
property of UIView
instead you can try (probably with-in tableview:cellForRowAtIndexPath:
):
A CALayer with a background color:
UIColor *bgColor = [UIColor greenColor];
CALayer* layer = [CALayer layer];
layer.frame = viewThatRequiresBGColor.bounds;
layer.backgroundColor = bgColor.CGColor;
[cell.viewThatRequiresBGColor.layer addSublayer:layer];
or a CAGradientLayer:
UIColor *startColor = [UIColor redColor];
UIColor *endColor = [UIColor purpleColor];
CAGradientLayer* gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = viewThatRequiresBGColor.bounds;
gradientLayer.colors = @[(id)startColor.CGColor, (id)endColor.CGColor];
gradientLayer.locations = @[[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:1]];
[cell.viewThatRequiresBGColor.layer addSublayer:gradientLayer];
I've also used a CALayer.border technique to provide a custom UITableView seperator:
// We have to use the borderColor/Width as opposed to just setting the
// backgroundColor else the view becomes transparent and disappears during
// the cell's selected/highlighted animation
UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake(0, 43, 1024, 1)];
separatorView.layer.borderColor = [UIColor redColor].CGColor;
separatorView.layer.borderWidth = 1.0;
[cell.contentView addSubview:separatorView];