问题 在单元格上设置角半径会导致UICollectionView的性能下降


我有一个 UICollectionView 只有几个细胞(约20个)。这个系列的性能非常好。但是,一旦我尝试绕过角落 UICollectionViewCells 这个视图正在渲染,我的表现受到重创。在我的单元格的init方法中,这是我添加的唯一一行导致这种情况:

[self.layer setCornerRadius:15];

由于这是在init方法中,我正在重新使用单元格,我不明白为什么这应该导致我的问题。

我尝试使用以下多种组合来调整销售的光栅化和不透明度,但仍然没有效果:

[self.layer setMasksToBounds:YES];
[self.layer setCornerRadius:15];
[self.layer setRasterizationScale:[[UIScreen mainScreen] scale]];
self.layer.shouldRasterize = YES;
self.layer.opaque = YES;

是他们的一些设置或技巧来提高性能 UICollectionView 有圆角的细胞?


7141
2017-12-20 20:24


起源

如果可能,使用预渲染图像来获得相同的效果 - 通过这些图层属性完成时,角半径和阴影相当昂贵。 - Till
细胞再利用也无济于事;要实现转角舍入,iOS必须重新计算在单元格移动时应该剪切的内容,如果有任何更改。虽然没有阴影那么糟糕。 - Jack Lawrence
我曾经想过要尝试这个,但是我试图避免它,因为我的单元格中有可变文本。另外,属性shouldRasterize = YES在渲染之前是否创建了图层? - lehn0058


答案:


正如@Till在评论中指出的那样,预呈现的图像应该可以解决您的性能问题。您可以将所有角落舍入,阴影和其他任何特殊效果放入其中,而不需要CA即时渲染它们。

预渲染图像不会将您锁定为静态内容大小,或者:查看 UIImage 可调整大小的图像 东东。 (这仍然比CA渲染每帧快。)


9
2017-12-20 22:52



确实。不过,如果你对图像不小心,你仍然可以获得可怕的表现。我们的设计师偶然在整个画布中将Photoshop的不透明度设置为95%,并将其导出到PNG中。滚动很糟糕,仪器显示整个图像是透明的。因此,如果您发现自己正在努力进行图像的不稳定滚动,请仔细检查其alpha值。 - Daniel Schneller


我发现这完全是因为调用了dequeuereusablecellwithidentifier。每次调用时,都需要重新渲染具有圆角的单元格。如果当项目滚动离开屏幕时集合视图没有从视图中删除它们,那么性能不会受到影响(只要它们在集合中没有太多项目)。看起来像一把双刃剑 - 两种方式都有其局限性。


1
2017-12-21 19:51





UIView子类有一个代码,它为您提供了一个带有不透明圆形边框和中间透明孔的视图。 您应该像往常一样创建所需的视图,之后您可以在视图上添加带孔的视图。可视化是 这里

如果您为UICollectionView或UITableView使用单色背景,它可以工作,您可以为每个单元格添加以下子视图:

@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

目标细胞类的示例:

- (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];
}

结果:  圆角视图作为单元格


1
2017-07-12 09:19





我通过在contentView上应用此半径而不是单元格本身来修复我的所有性能borderRadius问题。

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;

0
2017-08-31 16:28