I have a simple tableViewCell build in interface builder. It contains a UIView which contains an image. Now, when I select the cell, the default blue selection background is
Previously I have done as @P5ycH0 said (1x1 image stretched), but following @Brooks I figured that overriding -(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
in my custom UITableViewCell
implementation and resetting the the background colors after calling [super setHighlighted:highlighted animated:animated];
keeps my background colors when the cell is selected/highlighted
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
myView.backgroundColor = myColor;
}
The problem here is that the [super] implementation of
- (void) setSelected:(BOOL) selected animated:(BOOL) animated;
sets all the background colors in the UITableViewCell to rgba(0,0,0,0). Why? Perhaps to make us all sweat?
It is not that entire views disappear (as evidenced by the fact that if you change the views layer border properties, those are retained)
Here is the sequence of function calls that results from touching a cell
So your options are to
Unfortunately re-asserting the background colors in setHighlighted does nothing because setHighlighted is called before all the background colors get set to [r:0 b:0 g:0 a:0] by the first call to setSelected.
//TODO: Give a great description of how to override setSelected (stay tuned)
This issue may (finally) be resolved in iOS 13. Found this sweet paragraph in the iOS 13 beta 3 release notes.
The UITableViewCell class no longer changes the backgroundColor or isOpaque properties of the contentView and any of its subviews when cells become highlighted or selected. If you are setting an opaque backgroundColor on any subviews of the cell inside (and including) the contentView, the appearance when the cell becomes highlighted or selected might be affected. The simplest way to resolve any issues with your subviews is to ensure their backgroundColor is set to nil or clear, and their opaque property is false. However, if needed you can override the setHighlighted(:animated:) and setSelected(:animated:) methods to manually change these properties on your subviews when moving to or from the highlighted and selected states. (13955336)
https://developer.apple.com/documentation/ios_ipados_release_notes/ios_ipados_13_beta_3_release_notes
From that you said you built a tableViewCell using IB, I'd like to check whether you are adding your view as a subview of contentView
of UITableViewCell, not view
. The content view is the default superview for content displayed by the cell.
From the reference:
The content view of a UITableViewCell object is the default superview for content displayed by the cell. If you want to customize cells by simply adding additional views, you should add them to the content view so they will be positioned appropriately as the cell transitions into and out of editing mode.
In iOS 7, what worked for me is to override setSelected:animated:
in the UITableViewCell
subclass, but contrary to @Brooks' tip, I called [super setSelected:selected animated:animated]
.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Reassert the background color of the color view so that it shows
// even when the cell is highlighted for selection.
self.colorView.backgroundColor = [UIColor blueColor];
}
This lets me keep the system's default selection animation when the user taps on the cell, and also to deselect it in the table view delegate's didSelectRowAtIndexPath:
.
Here's my take on it. I have a subclass that all my cell inherit from, so that's the way I do it to avoid the background change in my UIImageViews:
override func setHighlighted(highlighted: Bool, animated: Bool) {
var backgroundColors = [UIView: UIColor]()
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
backgroundColors[imageView] = imageView.backgroundColor
}
}
super.setHighlighted(highlighted, animated: animated)
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
imageView.backgroundColor = backgroundColors[imageView]
}
}
}
override func setSelected(selected: Bool, animated: Bool) {
var backgroundColors = [UIView: UIColor]()
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
backgroundColors[imageView] = imageView.backgroundColor
}
}
super.setSelected(selected, animated: animated)
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
imageView.backgroundColor = backgroundColors[imageView]
}
}
}
This automaticlly fix the issue for all UIImageView
.