【问题标题】:CALayer - Shadow causes a performance hit?CALayer - 阴影会导致性能下降?
【发布时间】:2012-04-17 09:14:25
【问题描述】:

所以我在我的导航控制器上做一些自定义动画,以及它推动和弹出视图控制器的方式。

一切顺利。只要我添加以下代码(在UINavigationController 的子类中),我就会面临巨大的性能损失。添加阴影后,所有动画都变得非常滞后。这是预期的还是我在代码中做错了什么?

// This code gets called once during NavigationController initialization.
[self.view setClipsToBounds:NO];
[self.view.layer setCornerRadius:5];
[self.view.layer setShadowOffset:CGSizeMake(0, 20)];
[self.view.layer setShadowColor:[[UIColor yellowColor] CGColor]];
[self.view.layer setShadowRadius:20.0];
[self.view.layer setShadowOpacity:1];

编辑:

将我的阴影半径更改为 1,它仍然很慢

【问题讨论】:

  • 无论如何,这在 WWDC 2010 Session 425: Core Animation in Practice, Part 2 here.

标签: iphone ios uinavigationcontroller calayer shadow


【解决方案1】:
self.view.layer.shouldRasterize = YES;
self.view.layer.rasterizationScale = UIScreen.mainScreen.scale;

我最近遇到了一些缓慢的 CALayer 阴影问题,而那行简单的代码为我解决了一切问题!

【讨论】:

  • 太棒了,这让它表现得更好,现在我可以拥有任何大小的 shadowRadius 而不会影响性能
  • 这将忽略您可能需要注释的视网膜图像。要解决此问题,请添加以下行: self.view.layer.rasterizationScale = [UIScreen mainScreen].scale;
  • 我在 tableView 中遇到了类似的问题,其中每个单元格都包含一些 UILabel 以及带有圆角的视图。我向包含 tableView 的图层添加了一个阴影,并且滚动变得不稳定。但是,设置 shouldRasterize = YES 解决了不连贯的问题,但像素化了视图(明显模糊),因此它不是一个可接受的解决方案。我发现使用 shadowPath 而不是 shadowOffset 可以解决问题。
  • 如果视图变化可能会更糟。 shouldRasterize = YES 只有在视图没有变化的情况下才是好的解决方案,所以位图生成一次并被 UIScrollView 缓存和复用
  • 请注意,这会增加您的 RAM 使用率
【解决方案2】:

您应该预期添加阴影会减慢速度。 shadowRadius 为 20 非常高,而且会特别慢。

提高阴影渲染速度的另一个关键:设置shadowPath 属性。它可以提供很大帮助。

【讨论】:

  • 设置 ShadowPath 成功了,我的阴影半径是 10,它仍然表现良好。
  • @NicolasManzini 更多关于阴影性能的提示:stackoverflow.com/questions/10133109/…
  • 这是我测试的一种非常有效的方式... 使用 shouldRasterize 的想法工作并不像需要的那么快。这个答案要好得多!不明白为什么@williamcotton 的回答获得了这么多票...
  • shadowPath 成功了。性能感觉好一百万倍!
【解决方案3】:

使用shadowPath 代替shadowOffset。

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

查看此帖子:iphone - Animation's performance is very poor when view's shadow is on

【讨论】:

  • 工作起来就像一个魅力,比模糊视图和所有子层的 shouldRasterize 更好。
  • 这是我测试的一种非常有效的方式...... 使用 shouldRasterize 的想法工作并不像需要的那么快。这个答案要好得多!不明白为什么@williamcotton 的回答获得了这么多票...
  • shadowPath 很好也很快,但是如何在自动布局中保持更新帧呢?
  • 这仅适用于您的视图中没有圆角或透明度的情况。并非每个视图都是矩形的。 shouldRasterize 更通用,我们不必像所说的那样处理任何贝塞尔路径。
  • @TomSawyer 在视图的 layoutSubviews 中做,也许你需要子类一些视图
【解决方案4】:

是的,阴影非常昂贵(尤其是那么大的阴影——玩弄半径,您会发现它对您所经历的减速程度有很大的影响)。提高性能的一种方法是将其渲染一次到 CGImageContext 并仅显示该图像,而不是让图层在每次重绘时重新渲染阴影(但如果阴影需要动画或其他东西,这不起作用) .

【讨论】:

  • 您认为使用实际的 png 并将其添加到我的 UIView 会更好吗?
  • 如果有可能(即您事先知道阴影的形状/大小/任何内容),那么它肯定会给您带来更好的性能。 Blitting 图像比渲染阴影快得多。
  • 只要您不需要更改阴影形状,预渲染到图像就可以工作。
【解决方案5】:

斯威夫特 5.3。添加此代码。

myView -> UIView、collectionViewCell或者tableViewCell都可以。

myview.layer.shadowPath = UIBezierPath(rect: cell.bounds).cgPath
myview.layer.shouldRasterize = true
myview.layer.rasterizationScale = UIScreen.main.scale

【讨论】:

    【解决方案6】:

    我正在用“Neumorphism”风格编写应用程序,阴影太多,应用程序太滞后。但是使用下面这段代码,app很流畅。

    viewHasShadow.layer.shouldRasterize = true
    viewHasShadow.layer.rasterizationScale = UIScreen.main.scale
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多