无法添加角半径和阴影

Den*_*nis 33 iphone core-animation core-graphics objective-c quartz-graphics

我正在尝试在图像上绘制阴影和角半径.我可以单独添加它们,但我无法同时添加这两种效果.我正在添加一个阴影:

[layer setShadowOffset:CGSizeMake(0, 3)];
[layer setShadowOpacity:0.4];
[layer setShadowRadius:3.0f];
[layer setShouldRasterize:YES];
Run Code Online (Sandbox Code Playgroud)

这里,layer是UIView子类的CALayer.所以每当我设置时这都有用

[layer setMasksToBounds:NO];
Run Code Online (Sandbox Code Playgroud)

现在添加角半径我这样做:

[layer setCornerRadius:7.0f];
Run Code Online (Sandbox Code Playgroud)

但我需要将MasksToBounds设置为YES才能使其正常工作:

[layer setMasksToBounds:YES];
Run Code Online (Sandbox Code Playgroud)

无论如何我可以添加这两种效果吗?

谢谢你的时间,

丹尼斯

Mat*_*ong 59

是的,是的,有......

如果您同时需要角半径和投影,则不要打开-masksToBounds,而是设置角半径并使用圆角矩形设置阴影的贝塞尔曲线路径.保持两者的半径相同:

[layer setShadowOffset:CGSizeMake(0, 3)];
[layer setShadowOpacity:0.4];
[layer setShadowRadius:3.0f];
[layer setShouldRasterize:YES];

[layer setCornerRadius:12.0f];
[layer setShadowPath:
                   [[UIBezierPath bezierPathWithRoundedRect:[self bounds]
                                               cornerRadius:12.0f] CGPath]];
Run Code Online (Sandbox Code Playgroud)

在设置阴影路径后,可能需要在不设置-shouldRasterize参数的情况下检查性能.一旦设置了阴影路径,绘图性能往往非常好.

UPDATE

我在很长一段时间内没有看过这个问题,但似乎你不再需要设置一个shadowPath以便让它工作.只需设置cornerRadius并立即shadowOpacity工作.我认为这是iOS5以来的情况(据我所知).提供此更新可能是不必要的,因为设置这些参数"正常",但我会为后人提供它.回顾一下,现在就是您所需要的:

[layer setShadowOpacity:0.4];
[layer setCornerRadius:12.0f];
Run Code Online (Sandbox Code Playgroud)

如果仍需要更好的性能,可以继续设置shouldRasterize参数:

[layer setShouldRasterize:YES];
Run Code Online (Sandbox Code Playgroud)

说到性能,值得注意的是,如果你注意到动画迟缓,你会想要使用设置阴影路径的技术.此更新实际上只是指出不再需要设置路径来实现同时显示角半径和阴影的效果.但是,如果性能是您的首要任务,请使用路径.

更新2

由于人们似乎在某些情况下无法使用此功能,因此我将在此处创建的示例项目中发布更完整的代码段:

- (void)viewDidLoad
{
  [super viewDidLoad];

  CALayer *layer = [CALayer layer];
  [layer setBounds:CGRectMake(0.0f, 0.0f, 100.0f, 200.0f)];
  [layer setPosition:[[self view] center]];
  [layer setBackgroundColor:[[UIColor lightGrayColor] CGColor]];
  [layer setShadowOpacity:0.55f];
  [layer setCornerRadius:8.0f];
  [layer setBorderWidth:1.0f];

  [[[self view] layer] addSublayer:layer];

  [[[self testView] layer] setShadowOpacity:0.55f];
  [[[self testView] layer] setShadowRadius:15.0f];
  [[[self testView] layer] setCornerRadius:8.0f];
  [[[self testView] layer] setBorderWidth:1.0f];
}
Run Code Online (Sandbox Code Playgroud)

testView是我在Interface Builder中添加的UIView并设置了一个插座.这是为了确保它在您明确添加的两个图层以及子视图中的图层上的工作方式相同.

我已经在iOS5到iOS6.1的模拟器上进行了测试.它为我提供了这个结果:

在此输入图像描述

  • 这取决于您更新图层的频率.如果您打算将其设置一次而不是再次更新它,那么在为图层设置动画时,栅格化它将有助于提高性能.但是,如果图层的内容经常更新,则每次内容更改时,它都会将该内容呈现为图像,这实际上会损害您的滚动性能(假设您正在滚动/动画). (2认同)
  • @PaulBatum我使用的另一个技巧是使用多个图层.在图像图层上使用masksToBounds:YES,然后在图像图层后面创建一个提供阴影的图层. (2认同)