`

0928-CALayer

 
阅读更多

KVC(Key Value Coding)和KVO(Key Value Observer)

要在NSLog中输出有意义的对象,需要重写对象的description方法。要不只会输出对象的指针,而非对象内容

 

对象设置属性值时,person.name = @"Jake"的写法如果用KVC方式写的话则是[person setValue:@"Jake" forKey:@"name"],KVC的最大好处是可以降低对象之间的耦合度。或者属性是另一个对象时可使用KeyPath:[person set Value@"321" forKeyPath:@"card.no"];

取值则是[person valueForKey:@"name"],有对象层次关系时用[person valueForKeyPath:@"card.no"];

 

KVC的另外一个好处是可以使用一个dictionary将对象进行赋值初始化:如

Person *p = [[Person alloc] init];

[p setValuesForKeysWithDictionary:dictionary];

 

 

KVO 给一个对象添加观察者对象

给一个对象添加观察者对象可以监测该对象属性的变化,当改对象任意属性值发生变化时,设定的代理方法就被调用。给一个对象添加观察者的方法是调用对象的addObserver: forKeyPath: options: context:方法,所选择的观察者对象需要实现代理方法observeValueForKeyPath

注意:

1. 当监测结束时,需要移除观察者对象: removeObserver

2. 添加了观察者的对象需要是强引用或者被其他强引用对象弱引用了,要不观察者对象会和被销毁的对象绑定。

 

CALayer的基本使用

每一个UIView内部都有一个layer的属性,在实现核心动画的时候,本质上是将CALayer中的内容转换成位图,从而便于图形硬件的操作。

UIView和CALayer的关系:创建视图对象时,视图会自己创建一个图层,视图在绘图(如drawRect:)时,会将内容画在自己的根图层上。当视图在图层上完成绘图后,系统会将图层拷贝至屏幕。每个视图都有一个层,而每个图层又可以有多个子层。

Layer的设计目的是提供视图的基本可视内容,从而提高动画的执行效率,而不是为了取代视图。除提供可视内容外,Layer不负责视图的时间响应,内容绘制等工作,同时Layer不能参与到响应者链条中。

 

使用CALayer时的注意事项:

1. UIView中的CALayer只是一个类声明,因此需要在项目中添加QuartzCore框架

2. Quartz 2D是跨平台的,而UIKit只能使用在IOS系统中,因而如果需要使用颜色,不能直接使用UIColor,需要转换成CGColor。

 

CALayer具有以下基本属性,可以直接对layer的这些属性进行设值:

  • bounds: 设置宽度和高度
  • backgroundColor:背景颜色(CGColorRef类型)
  • borderColor: 边框颜色(CGColorRef类型)
  • borderWidth: 边框宽度
  • cornerRadius: 圆角半径
  • contents: 图层内容(CGImageRef)
  • transform: 旋转,缩放,平移
  • position: 位置
  • anchorPoint

对CALayer设置阴影时,需要同时设置三个属性:shadowColor, shadowOffset和shadowOpacity。

 

1. 在对UIImageView的图层layer做操作时,因为UIImageView不止有一个图层,所以必须设定imageView图层的遮罩属性,这样告诉layer将位于它之下的图层都遮盖住,这样才会显示对layer做的改动:

[imageView.layer setMasksToBounds:YES];

但如果对此做了设置,那么图层的阴影效果就会消失,因为被mask图层被遮盖住了。

 

2. CALayer的形变是3D的,因此形变参数中需要对x,y,z轴设置。

平移:[imageView.layer setTransform:CATransform3DMakeTranslation(0, -100, 0); //往上平移100点

缩放:[imageView.layer setTransform:CATransform3DMakeScale(0.5, 1.0, 1.0); //x轴缩小

旋转:[imageView.layer setTransform:CATransform3DMakeRotation(M_PI_2, 0, 0, 1.0) //这里x, y, z轴的含义是使图像沿着哪个轴旋转,如果是沿着z轴旋转,那么就是在屏幕平面上旋转。

 

3. 通过以上的setTransform方法设置形变,一次只能设置一个形变效果,如果设置多个的话,后面的形变设置会覆盖之前的形变设置。可以用keypath来一次设置多个形变。可以在xcode文档中查找transform3d关键字来找到对应的所有的keypath.

平移:[imageView.layer setValue: @-100 forKeyPath:@"transform.translation.y"];

缩放:[imageView.layer setValue:@0.5 forKeyPath:@"transform.scale"];

旋转:[imageView.layer setValue:@M_PI_2 forKeyPath:@"transform.rotation.z"];

 

4. 使用方法addSublayer将子图层添加到视图的根图层里时,图层所加的位置默认为视图的中心点,需要用setPosition对子图层设置中心位置,才能添加到正确的位置。图层layer的anchor point的值范围x轴,y轴各是0-1,anchorpoint是相对于图层本身来说的,如果anchorpoint值为0.5, 0.5,则为图层的中心点,如果值为1, 1 则为图层的右下角。 anchorpoint决定了图层的位置和旋转效果。因为在添加子图层时,是把子图层的anchorpoint对应到之前设置的position位置,图层旋转也是绕着anchorpoint进行旋转。所以通过改变图层的anchorPoint可以动态改变图层的位置

Tip: 可以根据自图层的锚点来实现图片的显示和隐藏。

 

CALayer的隐式动画属性

所有的非根图层都有隐式动画,所谓的隐式动画就是当改变动画属性时,相应的修改会自动产生动画效果。能执行隐式动画的称为“可动画属性”,如:bounds, position, opacity。可以在xcode里查找CALayer Animatable Properties来查看所有的隐式动画属性。

例如在touchBegan里修改layer的position属性,当手指点击屏幕时,layer的位置就会发生改变,同时伴随动画效果。

 

CALayer绘图

要在CALayer上绘图,有两种方法:
1.  创建一个CALayer的子类,然后重写drawInContext:方法,可以使用Quartz2D API在其中进行绘图

     用这种方式在CALayer上绘图的方法调用步骤为: 初始化UIView时,会自动调用UIView的代理方法drawLayer:inContext:(因为UIView默认是根视图的代理),然后这个方法会调用UIView的画图方法drawRect,如果drawRect方法里有绘图代码,先执行绘图代码最后执行子图层的drawInContext。因此UIView中drawRect里画的内容可能会被子图层的内容所覆盖。

2.  设置CALayer的delegate,然后让delegate实现drawLayer:inContext:方法进行绘图

 

注意:
1. 不能再将UIView设置为这个CALayer的delegate,因为UIView对象默认已经是它所包含的根图层的代理,将它设置成自图层的代理会出错
2. 无论使用哪种方法,都必须向层发送setNeedsDisplay消息,以触发相应绘图方法的调用

CALayer、UIView以及上下文之间的关系
1. 当UIView收到setNeedsDisplay消息时,CALayer会准备好一个CGContextRef,然后向它的delegate即UIView,发送消息,并且传入已经准备好的CGContextRef对象。UIView在drawLayer:inContext:方法中会调用自己的drawRect:方法
2. 平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由CALayer传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入CALayer的CGContextRef中,然后被拷贝至屏幕
3. CALayer的CGContextRef用的是位图上下文(Bitmap Graphics Context)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics