【问题标题】:Added a shadow to a UIImageView on a UITableView kills performance... why?在 UITableView 上向 UIImageView 添加阴影会降低性能......为什么?
【发布时间】:2012-03-29 19:21:18
【问题描述】:

我有一个UITableView,每个单元格有三个UIImageView 视图,一次在视图上显示三个单元格(总共九个UIImageView 视图)。把它想象成一个书架。有时我可以拥有多达 500 本书。

我在UIImageView 中添加了阴影,代码如下:

UIImageView *itemImageView = [[UIImageView alloc] initWithFrame:CGRectMake(25, 7, 65, 75)];
itemImageView.contentMode = UIViewContentModeScaleAspectFit;
itemImageView.tag = 6;
itemImageView.layer.shadowColor = [UIColor blackColor].CGColor;
itemImageView.layer.shadowOffset = CGSizeMake(3, -1);
itemImageView.layer.shadowOpacity = 0.7;
itemImageView.layer.shadowRadius = 3.0;
itemImageView.clipsToBounds = NO;
[cell.contentView addSubview:itemImageView];

当我添加阴影代码时,如上所示,滚动性能完全被扼杀并且变得不稳定。每个图像都有不同的Rect,因此必须在滚动时为每个项目创建阴影。有人对如何在UITableView 上为我的图像添加阴影而不遇到此问题有任何提示吗?

【问题讨论】:

标签: iphone objective-c ios xcode cocoa-touch


【解决方案1】:

如果添加,您可能会看到性能提升

itemImageView.layer.shadowPath =
       [UIBezierPath bezierPathWithRect:itemImageView.layer.bounds].CGPath;

但一般来说,像这样的层操作会降低表格视图的性能。我遇到了完全相同的问题,我们只是消除了阴影效果。这不值得。

【讨论】:

    【解决方案2】:

    您应该查看有关 CoreAnimation 最佳实践的 WWDC 视频。您可以请求将阴影的光栅化副本缓存在内存中。 Cocoa 的速度绝对足够快,可以即时渲染这些阴影,而不会退回到预渲染的图像。

    例子:

    itemImageView.layer.shouldRasterize = YES;
    

    我还对有关 UIBezierPath 的答案投了赞成票。最佳实践中也提到了这一点,但是设置 CALayer 的影子路径是一个巨大的性能提升。您还可以通过操纵阴影路径来创建一些有趣的特殊效果。

    【讨论】:

    • 添加 shouldRasterize = YES 绝对会影响图像质量。任何想法为什么?
    • 它为层次结构中的所有层重新使用一个光栅化图像。你是否也设置了阴影路径来提高图像质量?
    • 如果图层质量下降,很可能是 b/c,您需要添加代码:self.rasterizationScale = [[UIScreen mainScreen] scale]
    【解决方案3】:

    阴影很昂贵,会影响你的表现。

    更好的方法是在后台渲染阴影图像,缓存/保存它并在准备好时将其显示在视图上。

    编辑:您希望查看 Core Graphics / CGImage 例程。具体来说,CGContextSetShadowWithColor 会为您绘制阴影。

    http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html

    【讨论】:

    • 你说你的视图看起来像一个书架——至少对我来说,这意味着所有有阴影的东西都是矩形的(并且可能大小相同)。在这种情况下,重用相同的阴影图像绝对听起来像是要走的路。 (如果您的矩形大小不同,您仍然可以通过 UIImage 的可调整大小的图像支持重用该图像。)
    • 不一定是矩形。可以将阴影图像渲染到任意前景上,然后将其渲染到任意背景上。我的建议是缓存图像三明治(前景、阴影、背景)
    • 感谢 rickster...我所有的图像都是矩形的。我会试一试,然后根据需要调整它的大小,看看它的外观。
    【解决方案4】:

    在 tableviewcell 中为标签添加阴影时,我遇到了同样的问题。创建单元格时,我尝试在 cellForRowAtIndexPath 内布局元素:

    if(cell == nil){
        //layout cell
    

    这些优化了一点滚动,但它很不稳定。

    为了优化图片质量,如果您激活了“shouldRasterize”,您还应该添加 rasterizationScale:

    aLabel.layer.shouldRasterize = YES;
    aLabel.layer.rasterizationScale = [[UIScreen mainScreen] scale];
    

    也许有人对如何优化代码以获得正常的 iOS 滚动有一些想法。谢谢

    【讨论】:

      【解决方案5】:

      您是否激活重用?如果没有,则每次视图更改时(例如,在滚动期间),单元格都会重做。这肯定会消耗很多性能。

      【讨论】:

        【解决方案6】:

        在这里查看我的相同问题:App running slowly because of UIImageViews

        我会使用这个代码:

        imageView.layer.masksToBounds = NO;
        UIBezierPath *path = [UIBezierPath imageView.bounds];
        imageView.layer.shadowPath = path.CGPath;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-19
          • 2018-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-18
          • 2018-08-30
          相关资源
          最近更新 更多