暗影

laver自身是一块矩形区域,而暗影是作用于在整个非通明区域,并显现在一切layer的最下方。 依据画家算法,由远及近的烘托,暗影将会是是第一个被烘托的,可是暗影烘托有一个前提:咱们有必要已经画好了一切的layer和子layer。 所以这时咱们就需求一个临时缓存,这个缓存区就是离屏缓冲区,用来将一切layer都烘托完结,再依据一切layer和子layer组合后的图层的形状,增加暗影到FrameBuffer,最终显现到屏幕上。

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageNamed:@"111.jpg"];
imageView.center = CGPointMake(self.view.frame.size.width / 2, 200);
[self.view addSubview:imageView];
imageView.layer.shadowColor = UIColor.lightGrayColor.CGColor;
imageView.layer.shadowOpacity = 1.0;
imageView.layer.shadowRadius = 2.0;
imageView.layer.shadowOffset = CGSizeMake(5, 5);

离屏烘托:

[iOS开发]离屏烘托优化计划

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageNamed:@"111.jpg"];
imageView.center = CGPointMake(self.view.frame.size.width / 2, 200);
[self.view addSubview:imageView];
imageView.layer.shadowColor = UIColor.lightGrayColor.CGColor;
imageView.layer.shadowOpacity = 1.0;
imageView.layer.shadowRadius = 2.0;
//imageView.layer.shadowOffset = CGSizeMake(5, 5);
imageView.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(5, 5, imageView.frame.size.width, imageView.frame.size.height)].CGPath;

改成这样,就相当于知道了位置,能够先画暗影了:

[iOS开发]离屏烘托优化计划

此外还能够直接增加一个暗影图层或许运用Core Graphics制作暗影。

需求裁剪的layer

这种场景就包含咱们常用的圆角处理和clipsToBounds的处理。

留意:iOS官方针对UlImageView有一些优化:在iOS9之前,UllmageViewUIButton经过cornerRadius+masksToBounds 设置圆角都会触发离屏烘托,可是UImageView在iOS9今后,针对UIImageView中的image设置圆角并不会触发离屏烘托,假如加上了背景色或许暗影等其他作用仍是会触发离屏烘托的。

这个的优化计划前面提过了。

运用了mask的layer

layer.mask
  • mask是掩盖在一切layer及其子layer之上的,可能还带有一定的通明度。
  • mask也是需求等整个layer树制作完结,再加上mask和组合后的layer进行组合,所以需求拓荒一个独立于FrameBuffer的内存,用于将layer及其子layer画完,最终再和mask进行组合,存储到FrameBuffer,视频操控器从FrameBuffer中读取数据显现到屏幕上。

优化计划: 不运用mask,运用混合图层,在layer上方叠加相应mask形状的半通明layer

设置了组通明度为YES,并且通明度不为1的layer

  • group opacity中alpha并不是分别应用到每一层之上,需求整个layer树画完之后,在一致加上alpha,和底层其他layer的像素进行组合,此刻显然无法经过一次遍历就得到成果
  • 需求另外敞开一个独立内存,先将layer及其子layer画好,最终给组合后的图层加上alpha进行烘托,将最完结 果存储到帧缓冲区
  • GroupOpacity 敞开离屏烘托的条件是:laver.opacity!=1.0并且有子layer 或许背景图

优化计划: 封闭allowsGroupOpacity特点,依据产品需求自己操控layer通明度

采用了光栅化的layer

假如layer的layer.shouldRasterize被设置为true,会在触发离屏烘托的同时,将光栅化后的内容缓存起来,假如在下一次,对应的layer和子layer没有改动,则复用离屏缓冲区的成果,能够很大程度提升功能 。当视图内容是静态不变时,设置 shouldRasterize(光栅化)为YES,此计划最为实用方便。

imageView.layer.shouldRasterize = YES;
imageView.layer.rasterizationScale = imageView.layer.contentsScale;

但当视图内容是动态改动(如后台下载图片结束后切换到主线程设置)时,运用此计划反而增加体系负荷。

制作了文字的layer

想要在 UILabel 和 UITextView 上完成低成本的圆角(不触发离屏烘托),需求保证 layer 的contents出现通明的背 景色,文本视图类的layer 的contents默认是通明的(字符就在这个通明的环境里制作、显现),此刻只需求设置 la yer 的backgroundColor, 再加上cornerRacius就能够搞定了。不过 UlLabel 上设置backgroundColor的行为被更 改了,不再是设定layer 的背景色而是为contents设置背景色,UITextView 则没有改动这一点

  • 不要直接使用 labellbackaroundcolor =acolor 设置背景色
  • 不要直接在XIB中为label设置背景色
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 60)];
label.center = CGPointMake(self.view.frame.size.width / 2, 300);
[self.view addSubview:label];
label.text = @"我是label";
label.textAlignment = NSTextAlignmentCenter;
label.layer.borderColor = [UIColor blackColor].CGColor;
label.layer.borderWidth = 2;
label.layer.cornerRadius = 10;
label.layer.masksToBounds = YES;
label.backgroundColor = [UIColor systemCyanColor];

[iOS开发]离屏烘托优化计划

优化计划:

//label.layer.masksToBounds = YES;
//label.backgroundColor = [UIColor systemCyanColor];
label.layer.backgroundColor = [UIColor systemCyanColor].CGColor;

[iOS开发]离屏烘托优化计划

运用高斯含糊(毛玻璃)作用

iOS屏幕显现推送通知页面或许UIVisualEffectView

EDGE ANTIALIASING(抗锯齿)

不设置 allowsEdgeAntialiasing 特点为YES(默以为NO)

总结

  • RoundedCorner(圆角) 在仅指定cornerRadius时不会触发离屏烘托,仅适用于特殊情况:contents为 nil 或许contents不会遮挡背景色时的圆角。
  • Shawdow 能够经过指定路径来撤销离屏烘托。
  • Mask 无法撤销离屏烘托,能够使用混合图层来进行优化。