0928-CALayer

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

To output meaningful objects in NSLog, you need to override the object's description method. Or just output the pointer to the object, not the content of the object

 

When the object sets the attribute value, the writing method of person.name = @"Jake" is [person setValue:@"Jake" forKey:@"name"] if it is written in the KVC way. The biggest advantage of KVC is that it can reduce the number of objects between objects. degree of coupling. Or use KeyPath when the property is another object: [person set Value@"321" forKeyPath:@"card.no"];

The value is [person valueForKey:@"name"], and when there is an object hierarchy, use [person valueForKeyPath:@"card.no"];

 

Another benefit of KVC is that you can use a dictionary to initialize objects by assignment: such as

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

[p setValuesForKeysWithDictionary:dictionary];

 

 

KVO adds an observer object to an object

Adding an observer object to an object can monitor the change of the object's attributes. When any attribute value of the object changes, the set proxy method will be called. The way to add an observer to an object is to call the addObserver : forKeyPath : options : context : method of the object. The selected observer object needs to implement the proxy method observeValueForKeyPath   

Notice:

1. When the monitoring is over, the observer object needs to be removed: removeObserver

2. The object to which the observer is added needs to be strongly referenced or weakly referenced by other strongly referenced objects, or the observer object will be bound to the destroyed object.

 

Basic use of CALayer

Each UIView has a layer property inside. When implementing core animation, it essentially converts the content in the CALayer into a bitmap, which facilitates the operation of graphics hardware.

The relationship between UIView and CALayer: When creating a view object, the view will create a layer by itself, and when the view is drawing (such as drawRect:), it will draw the content on its own root layer. When the view finishes drawing on the layer, the system copies the layer to the screen. Each view has a layer, and each layer can have multiple sublayers.

Layers are designed to provide the basic visual content of a view to improve the efficiency of animation execution, not to replace the view. In addition to providing visual content, Layer is not responsible for the time response of the view, content drawing, etc. At the same time, Layer cannot participate in the responder chain.

 

Notes when using CALayer:

1. The CALayer in UIView is just a class declaration, so the QuartzCore framework needs to be added to the project

2. Quartz 2D is cross-platform, and UIKit can only be used in IOS system, so if you need to use color, you cannot use UIColor directly, you need to convert it to CGColor.

 

CALayer has the following basic properties, which can be directly set to these properties of the layer:

  • bounds: set width and height
  • backgroundColor: background color (CGColorRef type)
  • borderColor: border color (CGColorRef type)
  • borderWidth: border width
  • cornerRadius: corner radius
  • contents: layer contents (CGImageRef)
  • transform: rotate, scale, translate
  • position: position
  • anchorPoint

When setting shadows on CALayer, you need to set three properties at the same time: shadowColor, shadowOffset and 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)

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327105870&siteId=291194637