Iphone 在iOS上实现阴影的最快方法?

Iphone 在iOS上实现阴影的最快方法?,iphone,objective-c,ios,core-animation,shadow,Iphone,Objective C,Ios,Core Animation,Shadow,夸兹核心层阴影的吸吮表演。它们似乎需要在每次发生变化时重新渲染,从而导致所有内容都滞后 Coregraphics渐变(用于单向阴影)-看起来不正确。如果你的梯度从0.3 alpha变为0,它会有一些奇怪的效果,你可以“看到”它停止。这看起来不太好,也不自然。也许它没有抖动,但我肯定我听说核心图形渐变是。这很奇怪,我不知道 Coregraphics阴影-在设置它们时需要一段时间进行渲染,但在其他方面性能很好。这只是你等待视图出现的那一秒,因为它必须先渲染它的阴影,这就是问题所在 所以我肯定错过了什

夸兹核心层阴影的吸吮表演。它们似乎需要在每次发生变化时重新渲染,从而导致所有内容都滞后

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

Coregraphics阴影-在设置它们时需要一段时间进行渲染,但在其他方面性能很好。这只是你等待视图出现的那一秒,因为它必须先渲染它的阴影,这就是问题所在


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

添加阴影路径应该会大大提高性能。下面的示例假定您只希望视图侧面的阴影

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;

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

[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风格的滚动体验,这是您不希望看到的。如果需要设置视图动画或移动视图,请避免以任何方式创建圆角或阴影

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

以下是图纸代码:

- (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);
 }
请参阅此博客:

光栅化比例也让我有一段时间没注意到!你可以想象它会根据屏幕比例进行默认设置,但是没有:-/我有一个部分透明的PNG,带有锯齿状的边缘,我必须设置动画(当然是阴影)。它的大小是屏幕的2/3,所以有相当多的像素。此解决方案仍能完美运行。:)别忘了将
光栅化比例
设置到主屏幕的边界,否则生成的BMP将是非视网膜视图拉伸(这很难看)…编辑:我的意思是这是对我有效的解决方案,而
阴影路径
对我的性能没有影响。你是个天才@CHKL:您是否使用较旧的iPhone进行测试?iPhone5可以快速渲染阴影,但iPhone4在绘制阴影时会出现延迟和故障。本博客中的git存储库链接似乎不再有效。我应该如何在UICollectionViewCell上使用此代码?在UICollectionViewCell@trdavidson的子类中添加上述drawrect。我使用此代码已有一段时间了,但遇到了以下问题:单元格中的子视图未被剪裁,因此角点中的视图仍与圆角重叠。此外,在滚动时,某些单元格似乎“丢失”,根本无法获得阴影层。有什么想法可能导致这种情况吗?请确保在datasource delegate@trdavidson中调用[yourcell setNeedsToDisplay],查看您的问题是否仍然存在,哪些问题对性能更有利?使用UIBezierPath从捆绑或绘图加载UIImage(小于1kb)?