iOS开发经验专题:临时区iOS Developer

问题剖析:UITableViewCell选中后背景消失

2017-03-23  本文已影响482人  anjohnlv

在自定义UITableView时,我发现一个奇怪的现象:当我选择某个cell时,cell上自定义的分割线消失了。
我是这么做的,首先将tableView的系统分割线去除

[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

然后在cell的初始化方法中自定义了一个UIView,并加到了contentView的底部

UIView *line = [UIView new];
[line setBackgroundColor:[UIColor greenColor]];
[self.contentView addSubview:line];
[line mas_makeConstraints:^(MASConstraintMaker *make){
    make.left.equalTo(self.contentView);
    make.right.equalTo(self.contentView);
    make.height.mas_equalTo(@1);
    make.bottom.equalTo(self.contentView);
}];

再然后设置了cell的选中背景为透明

UIView *v = [UIView new];
[v setBackgroundColor:[UIColor clearColor]];
[self setSelectedBackgroundView:v];

完美实现,既可以自定义分割线,又可以自定义选中背景颜色,很灵活。

但是,为什么选中后分割线消失了?而且只是分割线消失了,cell上的其他label、button都还在。

经过试验分析,我发现并非是分割线消失了,而是contentView上所有的view的背景颜色被清除了,或者说被设置成透明了。包括UIView以及所有基于UIView的UILabel等。
那如何解决该问题,我提出以下三种方法:
1.设置cell为不可选的

[self setSelectionStyle:UITableViewCellSelectionStyleNone];

该方法最为简单,可以实现点击后背景颜色不变的需求。但是不灵活。
cell将不能被选中,自然不能自由控制选中的效果,也就避免了被选中时颜色被清除的问题。
2.重写cell上控件的setBackgroundColor方法

@interface CustomView : UIView 
- (void)setCustomBackgroundColor:(UIColor*)color;
@end

@implementation CustomView
- (void) setCustomBackgroundColor:(UIColor*)color {
    super.backgroundColor = color;
}
- (void)setBackgroundColor:(UIColor *)color {
    //空实现,系统清空背景色时会调到此处
}
@end

该方法可靠,也较灵活,就是麻烦了点,得重写所有有背景色的view。
3.重写cell的setSelected方法

-(void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    [line setBackgroundColor:[UIColor greenColor]];
}

这个方法就更加灵活了,还可以根据你的选中状态,分别设置不同的颜色。
那么问题来了,既然是选中时,系统默认清除了所有子控件的背景色,那么我不实现父类的方法可不可以?

-(void)setSelected:(BOOL)selected animated:(BOOL)animated {
    //[super setSelected:selected animated:animated];
    //我不实现super的选中方法,那是不是就不会自动清除颜色了呢?
}

结果证明我依旧想多了。不实现super的选中方法,cell将不会保持选择状态,但是点上去的时候,依旧会清除掉子控件的背景色。

留下的尾巴是:系统究竟是怎么实现选中时自动清除子控件背景色的?

大神们留下了一些有意思的方法,我去试着理解了一下。

直接将线加在cell

[self setBackgroundColor:[UIColor whiteColor]];
UIView *v = [UIView new];
[v setBackgroundColor:[UIColor grayColor]];
[self setSelectedBackgroundView:v];
[self.contentView setBackgroundColor:[UIColor brownColor]];
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make){
    make.left.and.top.and.right.equalTo(self);
    make.bottom.equalTo(self).offset(-10);
}];
line = [UIView new];
[line setBackgroundColor:[UIColor greenColor]];
[self addSubview:line];
[line mas_makeConstraints:^(MASConstraintMaker *make){
    make.left.and.bottom.and.right.equalTo(self);
    make.height.mas_equalTo(5);
}];

最终的效果是


gif.gif

可以看到,在contentView之外的自定义UIView的背景色仍然被清除了。
是我的理解还没到位吗?

上一篇下一篇

猜你喜欢

热点阅读