处理好cell上的圆角imageview使滑动更流畅
常常有将ImageView设置成圆角的需求,很常见的就是头像。通常用代码生成圆角:
avatarView.layer.cornerRadius = 36 / 2;
avatarView.layer.borderWidth = 0.5;
avatarView.layer.borderColor = [UIColor lightGrayColor].CGColor;
avatarView.clipsToBounds = YES;当每个Cell上有两个圆角ImageView的时候,滚动会明显卡顿。Cell虽然在复用,但是每次复用后都要再计算并绘制圆角。看来这绘制圆角运算量蛮大的。
###尝试通过另外一种方法来完成圆角需求
ImageView不要计算圆角,让设计师再给出张空心圆角图,圆角图除去空心外的其他区域颜色同Cell背景色,遮盖在ImageView的Image上。先管这一层叫ImageCover层。
测试,卡顿减轻许多。
这说明,Cell上尽量避免计算、绘制操作。
这时候bug来了,当按下Cell,Cell高亮时,ImageCover的颜色要保持与Cell背景色一致。
还得让设计师出张高亮图,就是把上面白色区域替换成高亮色,Cell默认按下色是(127,127,127)。
实现代码:
@interface HGRoundCornerImageView : UIImageView
@property (nonatomic, strong, readonly) UIImageView *coverImageView;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholderImage;
@end
@interface HGRoundCornerImageView()
@property (nonatomic, strong, readwrite) UIImageView *coverImageView;
@end
@implementation HGRoundCornerImageView
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
[self commonInit];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self commonInit];
}
return self;
}
- (void)commonInit {
self.contentMode = UIViewContentModeScaleAspectFit;
_coverImageView = [[UIImageView alloc] initWithFrame:self.bounds];
_coverImageView.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:_coverImageView];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholderImage
{
[self sd_setImageWithURL:url placeholderImage:placeholderImage]; // 这里使用到了SDWebImageView
}
- (void)layoutSubviews
{
[super layoutSubviews];
_coverImageView.frame = self.bounds;
}
@end###需要注意的地方 Cell里:
- (void)setAvatarImage:(UIImage *)image
{
[self.avatarView setImageWithURL:nil placeholderImage:image];
...
self.avatarView.coverImageView.highlighted = (self.isHighlighted || self.isSelected);
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
self.avatarView.coverImageView.highlighted = (self.isHighlighted || self.isSelected);
}Controller里:
- (void)tableView:(nonnull UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO]; // 这里一定要为NO
}作者 侯振永
写于2015 年 7月 1日