Setting corner radius on a cell kills UICollectionView's performance

∥☆過路亽.° 提交于 2019-12-01 03:24:39

As @Till noted in comments, a prerendered image should solve your performance problem. You can put all the corner rounding, shadowing, and whatever other special effects into that instead of needing CA to render them on the fly.

Prerendered images don't lock you into a static content size, either: look into the UIImage resizable image stuff. (That's still way faster than CA rendering every frame.)

I have found that this is caused entirely because of the call to dequeuereusablecellwithidentifier. Each time this is called, the cell with rounded corners needs to be re-rendered. If the collection view did not remove them from the view when the item scrolled off the screen, then the performance would not be affected (as long as their wasn't too many items in the collection that is). Seems like a double edged sword - both ways have their limits.

There is a code for UIView subclass, which is provide you a view with opaque rounded borders and transparent hole in the middle. You should create needed view as usual and after that you can add view with hole over your view. Visualisation is here.

It works if you use one-colored background for UICollectionView or UITableView, you can add following subview for each cell:

@interface TPRoundedFrameView : UIView

@property (assign, nonatomic) CGFloat cornerRadius;
@property (strong, nonatomic) UIColor * borderColor;

@end

@implementation TPRoundedFrameView

- (instancetype)init {
    if ((self = [super init])) {
        self.opaque = NO;
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    UIBezierPath * path = [UIBezierPath bezierPathWithRect:rect];
    UIBezierPath * innerPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:self.cornerRadius];
    [path appendPath:[innerPath bezierPathByReversingPath]];
    [self.borderColor set];
    [path fill];
}

@end

Example for target cell class:

- (void)awakeFromNib {
    [super awakeFromNib];
    // creating holed view with rounded corners
    self.myRoundedView.backgroundColor = [UIColor whiteColor];
    TPRoundedFrameView * roundedFrame = [TPRoundedFrameView new];
    roundedFrame.cornerRadius = 5.f;
    roundedFrame.borderColor = [UIColor groupTableViewBackgroundColor];

    // add borders to your view with appropriate constraints
    [self.myRoundedView addSubview:roundedFrame];

    roundedFrame.translatesAutoresizingMaskIntoConstraints = NO;
    NSDictionary * views = NSDictionaryOfVariableBindings(roundedFrame);
    NSArray * horizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[roundedFrame]-0-|" options:0 metrics:nil views:views];
    NSArray * vertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[roundedFrame]-0-|" options:0 metrics:nil views:views];
    [self.myRoundedView addConstraints:horizontal];
    [self.myRoundedView addConstraints:vertical];
}

Result: Table with rounded views as cells

I fixed all of my performance borderRadius issues by applying this radius on the contentView instead of the cell itself.

self.contentView.layer.borderWidth = 1.0f;
self.contentView.layer.cornerRadius = 5.0f;
self.contentView.layer.borderColor = [UIColor colorWithRed:202/255. green:202/255. blue:202/255. alpha:1.0].CGColor;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!