选择UITableViewCell时,UIView backgroundColor消失

P5y*_*cH0 69 interface-builder uitableview uiview ios

我在界面构建器中有一个简单的tableViewCell构建.它包含一个包含图像的UIView.现在,当我选择单元格时,会显示默认的蓝色选择背景,但我的UIView的backgroundColor消失了.

我的UITableViewCell的实现文件没有做任何特别的事情.它只是init和&返回self,我在setSelected中所做的就是调用super.

如何在选择tableView时显示我的UIView backgroundColor?

Bro*_*oks 108

这里的问题是[超级]实现

- (void) setSelected:(BOOL) selected animated:(BOOL) animated;
Run Code Online (Sandbox Code Playgroud)

将UITableViewCell中的所有背景颜色设置为rgba(0,0,0,0).为什么?也许是为了让我们大汗淋漓?

并不是整个视图都消失了(事实证明,如果更改视图图层边框属性,则会保留这些属性)

这是触摸单元格产生的函数调用序列

  1. setHighlighted
  2. touchesEnded
  3. layoutSubviews
  4. willSelectRowAtIndexPath(委托方)
  5. setSelected(!!!这是告诉所有视图背景颜色消失的地方)
  6. didSelectRowAtIndexPath(委托方)
  7. setSelected(再次)(有趣的是,这个调用没有清除背景颜色.这个超级方法里面有什么奇怪的东西?)
  8. layoutSubviews(再次)

所以你的选择是

  1. 覆盖- (void)setSelected:(BOOL)选择动画:(BOOL)动画; 不调用[super setSelected:selected animated:animated].这将为您提供技术上最正确的实现,因为a)代码被包含在UITableViewCell子类中,并且b)因为它仅在需要时被调用(需要时调用两次,但也许有办法解决).缺点是你必须重新实现setSelected的所有必要功能(而不是不必要的颜色清除功能).现在不要问我如何正确覆盖setSelected.你的猜测现在和我一样好(耐心等待,一旦我搞清楚,我就会编辑这个答案).
  2. didSelectRowAtIndexPath中重新断言背景颜色.这不是很好,因为它将实例代码放在实例之外.它有一个好处,它只在需要时调用,而不是......
  3. layoutSubviews中重新声明背景颜色.这根本不是很好,因为layoutSubviews被调用为数百万次!每次表格刷新时,每当你滚动时,每当你的祖母得到一个烫发时,它就会被调用......就像认真,一百万次一样.这意味着存在许多不必要的后台重新断言和大量额外的处理开销.从好的方面来说,它将代码放在UITableViewCell子类中,这很好.

不幸的是,在setHighlighted中重新断言背景颜色没有任何作用,因为在第一次调用setSelected所有背景颜色设置为[r:0 b:0 g:0 a:0]之前调用setHighlighted.

// TODO:详细说明如何覆盖setSelected(敬请关注)

  • 至少在iOS 7上,你也可以将单元格的`selectionStyle`设置为`UITableViewCellSelectionStyleNone`,它不会清除背景.唯一的缺点是它会忽略`selectedBackgroundView`属性. (10认同)

mie*_*tus 72

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    UIColor *backgroundColor = self.channelImageView.backgroundColor;
    [super setHighlighted:highlighted animated:animated];
    self.channelImageView.backgroundColor = backgroundColor;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    UIColor *backgroundColor = self.channelImageView.backgroundColor;
    [super setSelected:selected animated:animated];
    self.channelImageView.backgroundColor = backgroundColor;
}
Run Code Online (Sandbox Code Playgroud)


ZeC*_*dea 16

此前我已经照@ P5ycH0说(1x1图片拉伸),但以下@Brooks我想,覆盖-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated在我的自定义UITableViewCell执行和呼叫后重置的背景颜色[super setHighlighted:highlighted animated:animated];使我的背景颜色选择单元格时/高亮

-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    [super setHighlighted:highlighted animated:animated];
    myView.backgroundColor = myColor;
}
Run Code Online (Sandbox Code Playgroud)

  • 最佳方案 (2认同)

kub*_*lay 16

当您UITableViewCell被选中时,您应该注意两种状态:HighlightedSelected.

因此,对于具有自定义单元类的子场景UITableViewCell,您可以轻松地覆盖这两种方法以避免这种情况(Swift):

class MyCell: UITableViewCell {

    @IBOutlet var myView: UIView!

    override func setHighlighted(highlighted: Bool, animated: Bool) {
        let myViewBackgroundColor = myView.backgroundColor
        super.setHighlighted(highlighted, animated: animated)
        myView.backgroundColor = myViewBackgroundColor
    }

    override func setSelected(selected: Bool, animated: Bool) {
        let myViewBackgroundColor = myView.backgroundColor
        super.setSelected(selected, animated: animated)
        myView.backgroundColor = myViewBackgroundColor
    }

}
Run Code Online (Sandbox Code Playgroud)


Pat*_*tar 5

这个问题可以(最终)在iOS 13中得到解决。在iOS 13 beta 3发行说明中找到了这一甜蜜的段落。

当单元格变为突出显示或选中状态时,UITableViewCell类不再更改contentView及其任何子视图的backgroundColor或isOpaque属性。如果要在contentView内部(包括其中)的单元格的任何子视图上设置不透明的backgroundColor,则该单元格突出显示或选中时的外观可能会受到影响。解决子视图问题的最简单方法是确保将其backgroundColor设置为nil或clear,并且其opaque属性为false。但是,如果需要,您可以覆盖setHighlighted(:animated :)和setSelected(:animated :)方法,以在移入或移出突出显示和选定状态时手动更改子视图上的这些属性。(13955336)

https://developer.apple.com/documentation/ios_ipados_release_notes/ios_ipados_13_beta_3_release_notes