隱式動(dòng)畫
- 什么是隱式動(dòng)畫洒擦?
每一個(gè)UIView內(nèi)部都默認(rèn)有著一個(gè)CALayer谎倔,稱之為Root Layer(根層)亮曹,而所有的非Root Layer茅糜,即手動(dòng)創(chuàng)建的CALayer對(duì)象都默認(rèn)存在著隱式動(dòng)畫七芭,當(dāng)對(duì)這些手動(dòng)創(chuàng)建的CALayer的部分屬性進(jìn)行修改時(shí),就會(huì)默認(rèn)產(chǎn)生一些動(dòng)畫效果蔑赘,而這些屬性則稱之為可動(dòng)畫屬性--Animatable Properties狸驳。例如:bounds、backgroundColor米死、position等都是動(dòng)畫屬性锌历。
當(dāng)然,默認(rèn)的隱式動(dòng)畫也可以通過(guò)CATransaction來(lái)關(guān)閉:
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];
這里CALayer有兩個(gè)非常重要的屬性:
@property CGPoint position;
@property CGPoint anchorPoint;
-
position
屬性:用來(lái)設(shè)置CALayer在分層中的位置峦筒,以父層的左上角為原點(diǎn)究西。 -
anchorPoint
屬性:錨點(diǎn),是描述CALayer自身的物喷,決定著CALayer上哪個(gè)點(diǎn)定位在position屬性所在的父層的位置卤材,以自身的左上角為原點(diǎn)遮斥,默認(rèn)為CALayer的中點(diǎn)(0.5,0.5)扇丛,注意錨點(diǎn)的x术吗、y取值范圍為0~1。
隱式動(dòng)畫舉例:
- 效果:
- 實(shí)現(xiàn)代碼:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[CATransaction begin];
//設(shè)置事務(wù)有沒(méi)有動(dòng)畫
[CATransaction setDisableActions:NO];
//設(shè)置事務(wù)動(dòng)畫的執(zhí)行時(shí)長(zhǎng).
[CATransaction setAnimationDuration:1];
self.layer.bounds = CGRectMake(0, 0, arc4random_uniform(200), arc4random_uniform(200));
self.layer.position = CGPointMake(arc4random_uniform(300), arc4random_uniform(400));
self.layer.backgroundColor = [self randomColor].CGColor;
self.layer.cornerRadius = arc4random_uniform(50);
[CATransaction commit];
}
- (UIColor *)randomColor{
CGFloat r = arc4random_uniform(256) /255.0;
CGFloat g = arc4random_uniform(256) /255.0;
CGFloat b = arc4random_uniform(256) /255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:1];
}
核心動(dòng)畫
這里主要介紹iOS的幾種核心動(dòng)畫帆精。
- 基本動(dòng)畫
- 關(guān)鍵幀動(dòng)畫
- 動(dòng)畫組
- 轉(zhuǎn)場(chǎng)動(dòng)畫
核心動(dòng)畫(Core Animation)的動(dòng)畫執(zhí)行過(guò)程都是在后臺(tái)線程操作的较屿,不會(huì)阻塞主線程。
動(dòng)畫的繼承關(guān)系如下圖:
核心動(dòng)畫的使用步驟:
- 首先要有一個(gè)CALayer
- 初始化一個(gè)CAAnimation對(duì)象卓练,設(shè)置相關(guān)動(dòng)畫屬性
- 調(diào)用CALayer的
addAnimation:forKey:
方法隘蝎,將CAAnimation對(duì)象添加到CALayer中,開(kāi)始動(dòng)畫 - 調(diào)用CALayer的
removeAnimationForKey:
方法可停止CALayer中的動(dòng)畫
注意:CAAnimation是所有動(dòng)畫對(duì)象的父類襟企,負(fù)責(zé)控制動(dòng)畫的持續(xù)時(shí)間和速度嘱么,是個(gè)抽象類,不能直接使用顽悼,需使用它的子類曼振。CAAnimation的CAPropertyAnimation子類,也是抽象類蔚龙,不可直接使用冰评,需使用它的兩個(gè)子類CABasicAnimation和CAKeyframeAnimation。
使用效果
CABasicAnimation
- 效果
- 實(shí)現(xiàn)代碼:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"position";
anim.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
anim.removedOnCompletion = NO;
//保存動(dòng)畫最前面效果
anim.fillMode = kCAFillModeForwards;
[self.redView.layer addAnimation:anim forKey:nil];
}
CAKeyframeAnimation
- 效果:
- 實(shí)現(xiàn)代碼:
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
anim.keyPath = @"position";
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(140, 100)];
[path addLineToPoint:CGPointMake(160, 100)];
anim.path = path.CGPath;
anim.repeatCount = MAXFLOAT;
anim.autoreverses = YES;
anim.duration = 1;
[self.iconV.layer addAnimation:anim forKey:nil];
CATransition
- 效果:
- 實(shí)現(xiàn)代碼:
typedef enum : NSUInteger {
Fade = 1, //淡入淡出
Push, //推擠
Reveal, //揭開(kāi)
MoveIn, //覆蓋
Cube, //立方體
SuckEffect, //吮吸
OglFlip, //翻轉(zhuǎn)
RippleEffect, //波紋
PageCurl, //翻頁(yè)
PageUnCurl, //反翻頁(yè)
CameraIrisHollowOpen, //開(kāi)鏡頭
CameraIrisHollowClose, //關(guān)鏡頭
CurlDown, //下翻頁(yè)
CurlUp, //上翻頁(yè)
FlipFromLeft, //左翻轉(zhuǎn)
FlipFromRight, //右翻轉(zhuǎn)
} AnimationType;
- (void)CATransition{
//轉(zhuǎn)場(chǎng)代碼必須得要和轉(zhuǎn)場(chǎng)動(dòng)畫在同一個(gè)方法當(dāng)中.
//創(chuàng)建動(dòng)畫
CATransition *anim = [CATransition animation];
//設(shè)置轉(zhuǎn)場(chǎng)類型
anim.type = @"pageCurl";
//設(shè)置轉(zhuǎn)場(chǎng)的方向
anim.subtype = kCATransitionFromTop;
//設(shè)置動(dòng)畫的開(kāi)始點(diǎn).
anim.startProgress = 0.2;
//設(shè)置動(dòng)畫的結(jié)束點(diǎn).
anim.endProgress = 0.8;
anim.duration = 1;
[self.imageV.layer addAnimation:anim forKey:nil];
}
CAAnimationGroup
- 效果:
- 實(shí)現(xiàn)代碼:
-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
CAAnimationGroup *group = [CAAnimationGroup animation];
//縮放
CABasicAnimation *scaleAnim = [CABasicAnimation animation];
//設(shè)置屬性
scaleAnim.keyPath = @"transform.scale";
scaleAnim.toValue = @0.5;
//平移
CABasicAnimation *Anim = [CABasicAnimation animation];
//設(shè)置屬性
Anim.keyPath = @"position.y";
Anim.toValue = @(400);
group.animations = @[scaleAnim,Anim];
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
//添加動(dòng)畫
[self.redView.layer addAnimation:group forKey:nil];
}
這里要區(qū)分好UIView動(dòng)畫和核心動(dòng)畫的使用場(chǎng)景木羹,核心動(dòng)畫只作用在layer集索,核心動(dòng)畫修改的值都是假像,它的真實(shí)位置沒(méi)有發(fā)生變化汇跨。需要交互的用UIView,不需要進(jìn)行交互時(shí)兩個(gè)都可以使用。