《iOS核心动画高级技巧》笔记(二) - 图层几何学/视觉效果

图层几何学

  • 内部是如何根据父图层和兄弟图层来控制位置和尺寸的,如何管理图层的几何结构,如何被自动调整和自动布局影响的。

布局

  • <mark>UIView有三个比较重要的布局属性:frame,bounds 和 centerCALayer对应地叫做frame,bounds 和 position。</mark>
  • frame代表了图层的外部坐标
  • bounds是内部坐标
  • centerposition都代表了相对于父图层anchorPoint所在的位置。
  • 当操纵视图的frame,实际上是在改变位于视图下方CALayerframe,不能够独立于图层之外改变视图的frame
  • frame并不是一个非常清晰的属性,它其实是一个虚拟属性,是根据bounds,position和transform计算而来,所以当其中任何一个值发生改变,frame都会变化。相反,改变frame的值同样会影响到他们当中的值
  • 如图:当对图层做变换的时候,比如旋转或者缩放,frame实际上代表了覆盖在图层旋转之后的整个轴对齐的矩形区域,也就是说frame的宽高可能和bounds的宽高不再一致
3.2.jpeg

锚点

  • anchorPoint用单位坐标来描述,默认坐标是{0.5, 0.5}
  • 个人理解:如下图,中心点左右两边边距皆为视图宽度的一半,高度同理。改变视图中心点的位置至左上角后,同样有此规则,所以看到的视图向右下角移动了。
3.3.jpeg

坐标系

  • 一个图层的position依赖于它父图层的bounds

  • CALayer提供了一些方法(把定义在一个图层坐标系下的点或者矩形转换成另一个图层坐标系下的点或者矩形):

  • - (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer;

  • - (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer;

  • - (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer;

  • - (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;

  • 翻转的几何结构:

  • iOS:图层的position位于父图层的左上角

  • Mac OS:位于左下角

  • geometryFlipped:决定了一个图层的坐标是否相对于父图层垂直翻转,是一个BOOL类型。(它的所有子图层也同理,除非把它们的geometryFlipped属性也设为YES)。

  • 个人理解:设置为YES,假设原坐标系的起始点在左上角,现改成左下角,坐标系随之改变。

  • Z坐标轴

  • CALayer存在于一个三维空间当中,还有另外两个属性:

  • zPosition:最实用的功能就是改变图层的显示顺序(图层是根据它们子图层的sublayers出现的顺序来类绘制的),不能改变事件传递的顺序。

  • anchorPointZ:改变锚点在Z轴的位置。

点击测试

  • CALayer不直接处理触摸,手势事件,但有方法帮你处理事件。

  • -containsPoint::接受一个在本图层坐标系下的点,如果这个点在图层frame范围内就返回YES

  • [self.layerView.layer containsPoint:point]

  • -hitTest::接受一个在本图层坐标系下的点,如果这个点在图层frame范围内就返回图层本身,在之外则返回nil。测算的顺序严格依赖于图层树当中的图层顺序。

  • [self.layerView.layer hitTest:point]

  • 如果改变了图层的 Z 轴顺序,将不能检测到最前方的视图点击事件,因为被另一个视图遮盖住了,虽然zPosition值较小,但是在图层树中的顺序靠前。

自动布局

  • CALayer的布局
  • 通过CALayerDelegatelayoutDublayersOfLayer:函数。当图层的bounds发生改变或者图层的setNeedsLayout方法被调用的时候,该方法就会被执行。
  • 不能像UIView一样做到屏幕自适应,也是为什么使用视图而不是图层构建程序的原因之一。

视觉效果

圆角

  • conrnerRadius:圆角的曲率,只影响背景颜色而不影响背景图片或是子图层。可以通过把masksToBounds设置成YES,图层里面的所有东西都会被截取。
  • 创建一个有圆角和直角的图形可以通过图层蒙板或者CAShapeLayer

图层边框

  • borderWidth
  • borderColor:CGColorRef类型
  • 边框是跟随图层的边界变化的,而不是图层里面的内容

阴影

  • shadowOpacity:0(不可见) ~ 1(完全不透明)
  • shadowColor: 阴影的颜色
  • shadowOffset: 阴影的方向和距离,默认 {0, -3},宽度决定横向位移,高度决定纵向位移。(前身是 Mac OS,两者 Y 轴颠倒,Mac OS 阴影朝下,iOS就朝上了)
  • shadowRadius: 阴影模糊度

阴影裁剪

  • 图层的阴影继承自内容的外形,而不是根据边界和角半径来确定。
  • masksToBounds把阴影裁剪的解决办法:
  • 两个图层:一个只画阴影的空的外图层,一个用masksToBounds裁剪内容的内图层。

shadowPath属性

  • 计算阴影是个消耗性能的操作,通过该属性来告诉系统阴影的形状,提高性能。
  • CGPathRef类型,一个指向CGPath的指针,CGPath是一个Core Graphics对象,用来指定任意的一个矢量图形。
  • 该属性用来指定任意阴影形状

图层蒙版

  • mask属性:图层实心部分会被保留下来,其他地方会被抛弃。
Snip20170525_2.png
@interface ViewCOntroller
@property (nonatomic, weak) IBOutlet UIImageView *imageView
@end

@implementation ViewController
- (void)viewDidLoad{
      [super viewDidLoad];
      CALayer *maskLayer = [CALayer layer];
      maskLayer.frame = self.layerView.bounds;
      UIImage *maskImage = [UIImage imageNamed:@"Cone.png"];
      maskLayer.contents = (__bridge id)maskImage.CGImage;

      self.imageView.layer.mask = maskLayer;
}
@end

拉伸过滤

  • 以正确的比例和正确的1:1像素显示在屏幕上
    • 能够显示最好的画质,像素既没有被压缩也没有被拉伸。
    • 能更好的使用内存,因为这就是所有你要存储的东西。
    • 最好的性能表现,CPU不需要为此额外的计算。
  • minificationFilter:缩小图片,magnificationFilter:放大图片
  • kCAFilterLinear:默认值,采用双线性滤波算法,通过对多个像素取样最终生成新的值,得到一个平滑的表现不错的拉伸。但是当放大倍数比较大的时候图片就模糊不清。
  • kCAFilterTrilinear:和kCAFilterLinear非常相似,采用三线性滤波算法存储了多个大小情况下的图片(也叫多重贴图),并三维取样,同时结合大图和小图的存储进而�得到最后的结果。<mark>好处:在于算法能够从一系列已经接近于最终大小的图片中得到想要的结果,也就是说不要对很多像素同步取样。这不仅提高了性能,也避免了小概率因舍入错误引起的取样失灵的问题</mark>
  • kCAFilterNearest:采用最近过滤算法,取样最近的单像素点而不管其他的颜色。速度快不会产生模糊,但会降低质量并像素化图像,马赛克化。适用于比较小的图或者是差异特别明显,极少斜线的大图。

组透明

  • 如果你给一个图层设置了opacity属性,那它的子图层都会受此影响。
  • 当你显示一个50%透明度的图层时,图层的每个像素都会一半显示自己的颜色,另一半显示图层下面的颜色。这是正常的透明度的表现。
  • 但是如果图层包含一个同样显示50%透明的子图层时,你所看到的视图,50%来自子视图,25%来了图层本身的颜色,另外的25%则来自背景色。
  • 个人理解:当只有一个图层时,50%是自己的颜色,50%是背景的;当一个图层有一个子图层时,50%自己,另外50%的一半给父图层,一半给背景颜色。
Snip20170526_1.png
  • 整体透明解决方案:
  • 设置Info.plist文件中的UIViewGroupOpacityYES来达到这个效果,但会影响到这个应用其他部分。
  • CALayershouldRasterize属性为YES,在应用透明度之前,图层及其子图层都会被整合成一个整体的图片,这样就没有透明度混合的问题了

shouldRasterizeUIViewGroupOpacity一起的时候,性能问题就出现了)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容