1. Layer層錨點座標的理解
viewOne.layer.position = CGPointMake( 200.f, 200.f);
viewOne.layer.anchorPoint = CGPointMake(0.5f, 0.5f); //默認值爲0.5 0.5
viewOne.layer.bounds = CGRectMake(0.f, 0.f, 100.f, 100.f);
///position {200, 200} anchorPoint {1, 0}
///position {200, 200} anchorPoint {0.5, 0.5}
///position {200, 200} anchorPoint {0, 1}
///position {200, 200} anchorPoint {1, 1}
NSLog(@"position:%@,anchorPoint:%@",NSStringFromCGPoint(viewOne.layer.position),NSStringFromCGPoint(viewOne.layer.anchorPoint));
結論:1. 錨點和position這個點 是同一個點
2. 錨點是這個點相對於layer的座標, postion是這個點相對於父view 的座標
3. 錨點的取值範圍(0~1)
4. 旋轉/變換一個view 的時候, 是圍繞着錨點來做的旋轉和變換
應用: 時鐘的旋轉
//我們的layer或者view,你對它進行旋轉的時候,它是圍繞着錨點來旋轉的
//我寫一個秒針,我讓秒針來動
CALayer *secondLayer = [CALayer layer];
secondLayer.bounds = CGRectMake(0.f, 0.f, 10.f, 40.f);
secondLayer.position = CGPointMake(50.f, 50.f);
secondLayer.anchorPoint = CGPointMake(0.5f, 0.8f);
secondLayer.backgroundColor = [UIColor redColor].CGColor;
[viewTwo.layer addSublayer:secondLayer];
static int number = 0;
[NSTimer scheduledTimerWithTimeInterval:1.f repeats:YES block:^(NSTimer * _Nonnull timer) {
number++;
secondLayer.transform = CATransform3DMakeRotation(number*2*M_PI/60, 0, 0, 1);
}];
2. layContent
view有一個layer屬性, layer 的代理默認是view,layer內容的展示有兩個代理方法
///layer內容展示的兩個代理方法
- (void)displayLayer:(CALayer *)layer {
NSLog(@"%s", __func__);
layer.contents = (__bridge id)[UIImage imageNamed:@"1.png"].CGImage;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
NSLog(@"%s", __func__);
[super drawLayer:layer inContext:ctx];
}
3. 模型樹和呈現樹
layer層有三層樹結構:presentationLayer tree(呈現樹)、modelLayer tree(模型樹)、Render tree (渲染樹)
模型樹:用來存儲數據的、響應事件
呈現樹:用來根據模型樹的數據,展示
呈現樹是對模型樹的copy
如果添加了一個動畫,此時成現實的數據來源於動畫,而不是模型數據,當動畫結束之後,才又會根據模型樹的數據展示,模型樹的數據來源於動畫。
引申:每一個runloop循環的時候, 會提交一個事物:CATransaction,讓呈現樹根據數據展示。
4. 通過mask獲得不規則形狀
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(100.f, 100.f, 200.f, 200.f)];
imgView.image = [UIImage imageNamed:@"bg-mine.png"];
[self.view addSubview:imgView];
//通過layer.mask 來塑造一個不透明控件
UIImage *image = [UIImage imageNamed:@"bubble.png"];
CALayer *imageLayer = [CALayer layer];
imageLayer.contents = (__bridge id)image.CGImage;
imageLayer.frame = imgView.bounds;
imgView.layer.mask = imageLayer;
5. layer隱式動畫
/**
動畫的流程:有delegate,執行delegate,沒有的話尋找actions裏的action;然後再尋找style裏的action;defaultActionForKey;調用actionForKey,如果有action返回,那麼執行addAnimationForKey方法;
//上述流程,如果返回爲nil,繼續走流程,爲非nil,就停止
* 1. if defined, call the delegate method -actionForLayer:forKey:
* 2. look in the layer's `actions' dictionary
* 3. look in any `actions' dictionaries in the `style' hierarchy
* 4. call +defaultActionForKey: on the layer's class
*/
- (nullable id<CAAction>)actionForKey:(NSString *)event {
NSLog(@"%s", __func__);
NSLog(@"%@", [super actionForKey:event]);
return [super actionForKey:event];
}
+ (id<CAAction>)defaultActionForKey:(NSString *)event {
NSLog(@"%s", __func__);
return [super defaultActionForKey:event];
}
- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key {
NSLog(@"%s", __func__);
[super addAnimation:anim forKey:key];
}