37

QuartzCore .layer.shadow 吸收了性能。每次发生变化时,它们似乎都需要重新渲染,从而导致一切滞后。

Coregraphics 渐变(用于 1 向阴影)- 看起来不正确。如果您的渐变从 0.3 alpha 变为 0,它会产生一些奇怪的效果,您可以“看到”它停止。就是不好看,也不自然。也许它没有抖动,但我确信我听说核心图形渐变是。很奇怪,我不知道。

Coregraphics 阴影 - 设置它们时需要一些时间来渲染,但除此之外性能非常好。就在您等待视图出现的那一刻,因为它必须首先渲染它的阴影,这就是问题所在。

所以我一定错过了什么。是否有另一种看起来正确的方法,并且在渲染时间和性能方面都很快?

4

2 回答 2

106

添加 shadowPath 应该会给您带来巨大的性能提升。以下示例假设您只想要视图两侧的阴影

CGPathRef path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;
[view.layer setShadowPath:path];

编辑: 默认情况下,CALayer 在动画期间绘制阴影,以下代码允许您将阴影缓存为位图并重用它而不是重绘它:

self.view.layer.shouldRasterize = YES;
// Don't forget the rasterization scale
// I spent days trying to figure out why retina display assets weren't working as expected
self.view.layer.rasterizationScale = [UIScreen mainScreen].scale;
于 2012-04-12T23:17:41.920 回答
10

我经常看到人们使用巨大的性能影响视图的图层来创建圆角或阴影。像这样的东西:

[v.layer setCornerRadius:30.0f];
[v.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[v.layer setBorderWidth:1.5f];
[v.layer setShadowColor:[UIColor blackColor].CGColor];
[v.layer setShadowOpacity:0.8];
[v.layer setShadowRadius:3.0];
[v.layer setShadowOffset:CGSizeMake(2.0, 2.0)];
.....

这对性能有巨大的影响,尤其是阴影。将这样的视图放在 UITableView 中(或者事实上任何移动的东西)会创建一个 android-ish 滚动体验,你不希望这样。如果您需要动画或移动视图,请避免以任何方式创建圆角或阴影!

认识 Core Graphics
我创建了一个简单的 UIView 子类来向您展示如何以稍微不同的方式实现相同的结果。它使用 Core Graphics 来绘制视图,与上面的代码相比,它不会影响性能。

这是绘图代码:

- (void)drawRect:(CGRect)rect
{
   CGContextRef ref = UIGraphicsGetCurrentContext();

  /* We can only draw inside our view, so we need to inset the actual 'rounded content' */
  CGRect contentRect = CGRectInset(rect, _shadowRadius, _shadowRadius);

  /* Create the rounded path and fill it */
  UIBezierPath *roundedPath = [UIBezierPath bezierPathWithRoundedRect:contentRect cornerRadius:_cornerRadius];
  CGContextSetFillColorWithColor(ref, _fillColor.CGColor);
  CGContextSetShadowWithColor(ref, CGSizeMake(0.0, 0.0), _shadowRadius, _shadowColor.CGColor);
  [roundedPath fill];

  /* Draw a subtle white line at the top of the view */
  [roundedPath addClip];
  CGContextSetStrokeColorWithColor(ref, [UIColor colorWithWhite:1.0 alpha:0.6].CGColor);
  CGContextSetBlendMode(ref, kCGBlendModeOverlay);

  CGContextMoveToPoint(ref, CGRectGetMinX(contentRect), CGRectGetMinY(contentRect)+0.5);
  CGContextAddLineToPoint(ref, CGRectGetMaxX(contentRect),   CGRectGetMinY(contentRect)+0.5);
  CGContextStrokePath(ref);
 }

请参阅此博客: http ://damir.me/rounded-uiview-with-shadow-the-right-way

于 2014-08-21T09:54:12.443 回答