我有一个简单的tableViewCell界面构建在界面生成器中。它包含一个包含图像的UIView。
现在,当我选择该单元格时,默认的蓝色选定背景显示,但我的UIView的背景颜色消失了。
我的UITableViewCell实现文件没有做任何特殊处理。它只是初始化并返回self,在setSelected中,我只调用super。
如何使我的UIView背景颜色在选择tableView时显示?
我有一个简单的tableViewCell界面构建在界面生成器中。它包含一个包含图像的UIView。
现在,当我选择该单元格时,默认的蓝色选定背景显示,但我的UIView的背景颜色消失了。
我的UITableViewCell实现文件没有做任何特殊处理。它只是初始化并返回self,在setSelected中,我只调用super。
如何使我的UIView背景颜色在选择tableView时显示?
这里的问题是 [super] 的实现方式
- (void) setSelected:(BOOL) selected animated:(BOOL) animated;
将 UITableViewCell 中所有背景颜色设置为 rgba(0,0,0,0)。为什么呢?可能是为了让我们出一身汗吧?
并不是整个视图都消失了(因为如果更改视图的层边框属性,它们会保留)。
以下是触摸单元格时导致的函数调用序列:
因此,您有以下选项:
不幸的是,在 setHighlighted 中重新断言背景颜色什么也没做,因为在第一次调用 setSelected 之前就会调用 setHighlighted。
// TODO: 提供如何正确重写 setSelected 的描述(敬请关注)
selectionStyle
设置为 UITableViewCellSelectionStyleNone
,这样它就不会清除背景。唯一的缺点是它会忽略 selectedBackgroundView
属性。 - Austin- (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;
}
当你的UITableViewCell
被选中时,你需要关注两种状态:Highlighted
和Selected
。
因此,对于那些拥有自定义单元格类(是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
}
}
之前我按照 @P5ycH0 的建议(拉伸1x1像素图像)完成了,但是在遵循 @Brooks 的建议后,我发现覆盖我的自定义UITableViewCell
实现中的-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
方法,并在调用[super setHighlighted:highlighted animated:animated];
之后重置背景颜色,可以在单元格被选择/高亮时保留我的背景颜色。
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
myView.backgroundColor = myColor;
}
setHighlighted
函数是用来在单元格被选中时添加自定义行为的,顺便说一句,做得很好。 - Wendy LigaselectedBackgroundView
变得过时 :( 因为它可能会保持隐藏状态。 - Vilém KurzBrooks已经对为什么会发生这种情况做了很好的解释,但我认为我有更好的解决方案。
在您的子视图中,重写setBackgroundColor:
到您想要的任何颜色。设置器仍将被调用,但只强制实施您指定的颜色。
- (void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:[UIColor whiteColor]];
}
好的,当UIView类在选定的tableviewcell中时,失去背景颜色是正常行为。我无法找到防止此情况发生的方法。现在,我只是将UIView替换为UIImageView,其中包含一个拉伸的1x1白像素。在我看来很丑,但它可以工作。
您需要在自定义单元格中覆盖下面两个方法:
- (void) setSelected:(BOOL)selected animated:(BOOL)animated;
- (void) setHighlighted:(BOOL)highlighted animated:(BOOL)animated;
[super setSelected:animated:]
和[super setHighlighted:animated:]
;UITableViewCell
样式,您应该为自定义单元格设置UITableViewCellSelectionStyleNone
选择样式;- (void) setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
[self setHighlightedSelected:highlighted animated:animated];
}
- (void) setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self setHighlightedSelected:selected animated:animated];
}
- (void) setHighlightedSelected:(BOOL)selected animated:(BOOL)animated
{
void(^selection_block)(void) =
^
{
self.contentView.backgroundColor = selected ? SELECTED_BACKGROUND_COLOR : NORMAL_BACKGROUND_COLOR;
};
if(animated)
{
[UIView animateWithDuration:SELECTION_ANIMATION_DURATION
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:selection_block
completion:NULL];
}
else
selection_block();
}
contentView
是 UITableViewCell
的一个属性,它出现在 iOS 7 中。请注意,您可以使用自己的单元格子视图或视图来代替它。
摘要
该解决方案使您能够锁定单元格的某些背景颜色,而其余部分由系统行为控制。
根据mientus的答案, 我创建了一种解决方案,允许您指定哪些视图应该保留其背景颜色。
这仍然允许其他单元格子视图在突出显示/选择时删除它们的背景,而且这是我们的唯一解决方案(两个视图需要永久背景)。
我采用了面向协议编程的方法,使用BackgroundLockable
协议包含锁定视图列表,并在保持颜色的同时运行一个闭包:
protocol BackgroundLockable {
var lockedBackgroundViews: [UIView] { get }
func performActionWithLockedViews(_ action: @escaping () -> Void)
}
extension BackgroundLockable {
func performActionWithLockedViews(_ action: @escaping () -> Void) {
let lockedViewToColorMap = lockedBackgroundViews.reduce([:]) { (partialResult, view) -> [UIView: UIColor?] in
var mutableResult = partialResult
mutableResult[view] = view.backgroundColor
return mutableResult
}
action()
lockedViewToColorMap.forEach { (view: UIView, color: UIColor?) in
view.backgroundColor = color
}
}
}
然后我有一个UITableViewCell
的子类,它重写了高亮和选中操作以运行协议闭包中调用默认(超级)行为:
class LockableBackgroundTableViewCell: UITableViewCell, BackgroundLockable {
var lockedBackgroundViews: [UIView] {
return []
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
performActionWithLockedViews {
super.setHighlighted(highlighted, animated: animated)
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
performActionWithLockedViews {
super.setSelected(selected, animated: animated)
}
}
}
LockableBackgroundTableViewCell
或在单元格类中使用BackgroundLockable
协议,就可以轻松地向某些单元格添加锁定行为了!class SomeCell: LockableBackgroundTableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var button: UIButton!
override var lockedBackgroundViews: [UIView] {
return [label, icon]
}
}
Swift 4
在您的UITableViewCell类中:
override func setSelected(_ selected: Bool, animated: Bool) {
myView.backgroundColor = UIColor.blue
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
myView.backgroundColor = UIColor.blue
}