IOS動畫

動畫的繼承結構

CAAnimation{CAPropertyAnimation{CABasicAnimation{CASpringAnimation}CAKeyframeAnimation}CATransitionCAAnimationGroup}

CAAnimation(動畫根類,不可以直接使用)

CAAnimation-屬性(復雜點的屬性,下面會有詳細解釋)

//動畫的代理回調,下面會有@property(nullable,strong)iddelegate;//動畫執行完以后是否移除動畫,默認YES@property(getter=isRemovedOnCompletion)BOOLremovedOnCompletion;//動畫的動作規則,包含以下值//kCAMediaTimingFunctionLinear 勻速//kCAMediaTimingFunctionEaseIn 慢進快出//kCAMediaTimingFunctionEaseOut 快進慢出//kCAMediaTimingFunctionEaseInEaseOut 慢進慢出 中間加速//kCAMediaTimingFunctionDefault 默認@property(nullable,strong)CAMediaTimingFunction*timingFunction;

以上屬性的詳解:

委托:動畫執行的代理,在動畫開始前設定,不用顯式的寫在代碼里,它包含兩個方法:

動畫開始回調

- (void)animationDidStart:(CAAnimation *)anim;

動畫結束回調

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

removedOnCompletion:動畫完成后是否移除動畫默認為YES此屬性為YES時,在fillMode不可用,具體為什么不可用,可以自己結合兩個屬性分析一下,這里不再贅述。

timingFunction設置動畫速度曲線,默認值上面已經給出下面說它的幾個方法:

。這兩個方法是一樣的如果我們對系統自帶的速度函數不滿意,可以通過這兩個函數創建一個自己喜歡的速度曲線函數,具體用法可以參考這篇文章CAMediaTimingFunction使用的

+ (instancetype)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

- (instancetype)initWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

電子雜志曲線的函數的緩沖點,具體用法可以參考這篇文章:iOS-核心動畫高級編程/ 10-緩沖

- (void)getControlPointAtIndex:(size_t)idx values:(float[2])ptr;

CAAnimation 協議的屬性

//開始時間.這個屬性比較復雜,傻瓜用法為:CACurrentMediaTime() + x,//其中x為延遲時間.如果設置 beginTime = CACurrentMediaTime() + 1.0,產生的效果為延遲一秒執行動畫,下面詳解原理@propertyCFTimeIntervalbeginTime;//動畫執行時間,此屬性和speed有關系speed默認為1.0,如果speed設置為2.0,那么動畫執行時間則為duration*(1.0/2.0).@propertyCFTimeIntervalduration;//動畫執行速度,它duration的關系參考上面解釋@propertyfloatspeed;//動畫的時間延遲,這個屬性比較復雜,下面詳解@propertyCFTimeIntervaltimeOffset;//重復執行次數@propertyfloatrepeatCount;//重復執行時間,此屬性優先級大于repeatCount.也就是說如果repeatDuration設置為1秒重復10次,那么它會在1秒內執行完動畫.@propertyCFTimeIntervalrepeatDuration;//是否自動翻轉動畫,默認NO.如果設置YES,那么整個動畫的執行效果為A->B->A.@propertyBOOLautoreverses;//動畫的填充方式,默認為: kCAFillModeRemoved,包含以下值//kCAFillModeForwards//動畫結束后回到準備狀態//kCAFillModeBackwards//動畫結束后保持最后狀態//kCAFillModeBoth//動畫結束后回到準備狀態,并保持最后狀態//kCAFillModeRemoved//執行完成移除動畫@property(copy)NSString*fillMode;

以上屬性的詳解:

BEGINTIME:剛才上面簡單解釋了下這個屬性的用法:CACurrentMediaTime()+ x。會使動畫延遲執行點ˉx秒不知道到這里有沒有人想過如果-x?會出現怎么樣效果假設我們有執行一個3秒的動畫,設置然后beginTime = CACurrentMediaTime()- 1.5那么執行動畫你會發現動畫只會執行后半段,就是也。只執行后面的3-1.5s的動畫。為什么會這樣?其實動畫都有一個時間表(時間線)的概念。動畫開始執行都是基于這個時間線的絕對時間,這個時間和它的父類有關(系統的屬性注釋可以看到)。默認的CALayer的的BEGINTIME為零,如果這個值為零的話,系統會把它設置為CACurrentMediaTime(),那么這個時間就是正常執行動畫的時間:立即執行所以如果設置你beginTime=CACurrentMediaTime()+x;它會把它的執行時間線推遲x秒,就是也。晚執行x秒,如果你beginTime=CACurrentMediaTime()-x;那它開始的時候會從你動畫對應的絕對時間開始執行。

timeOffset:時間偏移量,默認為0;既然它是時間偏移量,那么它即和動畫時間相關這么解釋:假設我們設置一個動畫時間為5秒,動畫執行的過程為1->2->3->4->5,這時候如果你設置timeOffset = 2s它那么的執行過程就會變成3->4->5->1->2如果你設置timeOffset = 4s那么它的執行過程就會變成5->1->2->3->4,這么說應該很明白了吧?

CAPropertyAnimation屬性動畫,抽象類,不能直接使用

CAPropertyAnimation的屬性

//需要動畫的屬性值@property(nullable,copy)NSString*keyPath;//屬性動畫是否以當前動畫效果為基礎,默認為NO@property(getter=isAdditive)BOOLadditive;//指定動畫是否為累加效果,默認為NO@property(getter=isCumulative)BOOLcumulative;//此屬性相當于CALayer中的transform屬性,下面會詳解@property(nullable,strong)CAValueFunction*valueFunction;

以上屬性的詳解:

CAPropertyAnimation是屬性動畫顧名思義也就是針對屬性才可以做的動畫那它可以對誰的屬性可以做動畫是的CALayer的屬性,比如:?界限,位置等那么問題來了,我們改變的CALayer的位置可以。設置直接[CAPropertyAnimation animationWithKeyPath:@"position"]如果我們設置它的變換(CATransform3D)呢?CATransform3D是一個矩陣,如果我們想為它做動畫怎么辦?下面這個屬性就是用來解決這個問題的。

valueFunction:我們來看它可以設置的值:

kCAValueFunctionRotateX

kCAValueFunctionRotateY

kCAValueFunctionRotateZ

kCAValueFunctionScale

kCAValueFunctionScaleX

kCAValueFunctionScaleY

kCAValueFunctionScaleZ

kCAValueFunctionTranslate

kCAValueFunctionTranslateX

kCAValueFunctionTranslateY

kCAValueFunctionTranslateZ

說到這里大家應該都知道該怎么用了吧?。

CAPropertyAnimation的方法

//通過key創建一個CAPropertyAnimation對象+ (instancetype)animationWithKeyPath:(nullableNSString*)path;

下面我們來看一下可以設置屬性動畫的屬性歸總:

CATransform3D{

rotation旋轉

transform.rotation.x

transform.rotation.y

transform.rotation.z

scale縮放

transform.scale.x

transform.scale.y

transform.scale.z

translation平移

transform.translation.x

transform.translation.y

transform.translation.z

}CGPoint{

position

position.x

position.y

}CGRect{

bounds

bounds.size

bounds.size.width

bounds.size.height

bounds.origin

bounds.origin.x

bounds.origin.y

}property{

opacity

backgroundColor

cornerRadius

borderWidth

contents

Shadow{

shadowColor

shadowOffset

shadowOpacity

shadowRadius

}}

總結:CAAnimation是基類,CAPropertyAnimation是抽象類,兩者都不可以直接使用,那我們只有使用它的子類了。

CABasicAnimation基本動畫

CABasicAnimation的屬性

//開始值@property(nullable,strong)idfromValue;//結束值@property(nullable,strong)idtoValue;//結束值@property(nullable,strong)idbyValue;

這三個屬性之間的規則

fromValue狀語從句:toValue不為空,的動畫會效果從fromValue的值變化到toValue。

fromValue狀語從句:byValue都不為空,的動畫效果將會從fromValue變化到fromValue+byValue

toValue狀語從句:byValue都不為空,的動畫效果將會從toValue-byValue變化到toValue

只有fromValue的值不為空,的動畫效果將會從fromValue的值變化到當前的狀態。

只有toValue的值不為空,的動畫效果將會從當前狀態的值變化到toValue的值。

只有byValue的值不為空,動畫的效果將會從當前的值變化到(當前狀態的值+byValue)的值。

CABasicAnimation看起來不太復雜,但實際只用這個就足以可以做很多種動畫了,下面簡單用一下,先看效果:

CABasicAnimation.gif

然后再看下實現代碼:

#import"ViewController.h"#import"TFEasyCoder.h"@interfaceViewController()@property(nonatomic,strong)UIView*demoView;@end@implementationViewController- (void)viewDidLoad {? ? [superviewDidLoad];? ? kdeclare_weakself;NSArray*titles = @[@"淡入淡出",@"縮放",@"旋轉",@"平移"];for(unsignedinti =0; i < titles.count; i++) {? ? ? ? [UIButtoneasyCoder:^(UIButton*ins) {? ? ? ? ? ? [weakSelf.viewaddSubview:ins];? ? ? ? ? ? ins.backgroundColor= [UIColorbrownColor];? ? ? ? ? ? ins.tag= i;? ? ? ? ? ? ins.frame=CGRectMake(10,50+80* i,100,60);? ? ? ? ? ? [ins setTitle:titles[i] forState:UIControlStateNormal];? ? ? ? ? ? [ins addTarget:selfaction:@selector(animationBegin:) forControlEvents:UIControlEventTouchUpInside];? ? ? ? }];? ? }? ? [UIVieweasyCoder:^(UIView*ins) {? ? ? ? ins.frame=CGRectMake(0,0,100,100);? ? ? ? ins.backgroundColor= [UIColorredColor];? ? ? ? ins.center=self.view.center;? ? ? ? weakSelf.demoView= ins;? ? ? ? [weakSelf.viewaddSubview:weakSelf.demoView];? ? }];}-(void)animationBegin:(UIButton*)btn{CABasicAnimation*animation =nil;switch(btn.tag) {case0:{//淡如淡出animation = [CABasicAnimationanimationWithKeyPath:@"opacity"];? ? ? ? ? ? [animation setFromValue:@1.0];? ? ? ? ? ? [animation setToValue:@0.1];? ? ? ? }break;case1:{//縮放animation = [CABasicAnimationanimationWithKeyPath:@"transform.scale"];? ? ? ? ? ? [animation setFromValue:@1.0];//設置起始值[animation setToValue:@0.1];//設置目標值}break;case2:{//旋轉animation = [CABasicAnimationanimationWithKeyPath:@"transform.rotation"];//setFromValue不設置,默認以當前狀態為準[animation setToValue:@(M_PI)];? ? ? ? }break;case3:{//平移animation = [CABasicAnimationanimationWithKeyPath:@"position"];//setFromValue不設置,默認以當前狀態為準[animation setToValue:[NSValuevalueWithCGPoint:CGPointMake(self.view.center.x,self.view.center.y+200)]];? ? ? ? }break;default:break;? ? }? ? [animation setDelegate:self];//代理回調[animation setDuration:0.25];//設置動畫時間,單次動畫時間[animation setRemovedOnCompletion:NO];//默認為YES,設置為NO時setFillMode有效/**

*設置時間函數CAMediaTimingFunction

*kCAMediaTimingFunctionLinear 勻速

*kCAMediaTimingFunctionEaseIn 開始速度慢,后來速度快

*kCAMediaTimingFunctionEaseOut 開始速度快 后來速度慢

*kCAMediaTimingFunctionEaseInEaseOut = kCAMediaTimingFunctionDefault 中間速度快,兩頭速度慢

*/[animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut]];//設置自動翻轉//設置自動翻轉以后單次動畫時間不變,總動畫時間增加一倍,它會讓你前半部分的動畫以相反的方式動畫過來//比如說你設置執行一次動畫,從a到b時間為1秒,設置自動翻轉以后動畫的執行方式為,先從a到b執行一秒,然后從b到a再執行一下動畫結束[animation setAutoreverses:YES];//kCAFillModeForwards//動畫結束后回到準備狀態//kCAFillModeBackwards//動畫結束后保持最后狀態//kCAFillModeBoth//動畫結束后回到準備狀態,并保持最后狀態//kCAFillModeRemoved//執行完成移除動畫[animation setFillMode:kCAFillModeBoth];//將動畫添加到layer,添加到圖層開始執行動畫,//注意:key值的設置與否會影響動畫的效果//如果不設置key值每次執行都會創建一個動畫,然后創建的動畫會疊加在圖層上//如果設置key值,系統執行這個動畫時會先檢查這個動畫有沒有被創建,如果沒有的話就創建一個,如果有的話就重新從頭開始執行這個動畫//你可以通過key值獲取或者刪除一個動畫://[self.demoView.layer animationForKey:@""];//[self.demoView.layer removeAnimationForKey:@""][self.demoView.layeraddAnimation:animation forKey:@"baseanimation"];}/**

*? 動畫開始和動畫結束時 self.demoView.center 是一直不變的,說明動畫并沒有改變視圖本身的位置

*/- (void)animationDidStart:(CAAnimation*)anim{NSLog(@"動畫開始------:%@",NSStringFromCGPoint(self.demoView.center));}- (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag{NSLog(@"動畫結束------:%@",NSStringFromCGPoint(self.demoView.center));}

以上效果和代碼還有注釋都解釋的很詳細了,然后源碼在這里:人口統計學基本動畫

CASpringAnimation彈性動畫

CASpringAnimation的屬性(iOS9新加)

//理解下面的屬性的時候可以結合現實物理現象,比如把它想象成一個彈簧上掛著一個金屬小球//質量,振幅和質量成反比@propertyCGFloatmass;//剛度系數(勁度系數/彈性系數),剛度系數越大,形變產生的力就越大,運動越快@propertyCGFloatstiffness;//阻尼系數,阻止彈簧伸縮的系數,阻尼系數越大,停止越快,可以認為它是阻力系數@propertyCGFloatdamping;//初始速率,動畫視圖的初始速度大小速率為正數時,速度方向與運動方向一致,速率為負數時,速度方向與運動方向相反.@propertyCGFloatinitialVelocity;//結算時間,只讀.返回彈簧動畫到停止時的估算時間,根據當前的動畫參數估算通常彈簧動畫的時間使用結算時間比較準確@property(readonly)CFTimeIntervalsettlingDuration;

下面我們寫一個演示看看效果:

彈簧彈性動畫.gif注意

以上GIF的代碼為:

CASpringAnimation*spring = [CASpringAnimationanimationWithKeyPath:@"position.y"];spring.damping=5;spring.stiffness=100;spring.mass=1;spring.initialVelocity=0;spring.duration= spring.settlingDuration;spring.fromValue= @(self.demoView1.center.y);spring.toValue= @(self.demoView1.center.y+ (btn.selected?+200:-200));spring.fillMode= kCAFillModeForwards;[self.demoView1.layeraddAnimation:spring forKey:nil];

CASpringAnimation效果不錯,但是很不幸只有iOS9 +系統才能使用,這就很操蛋了以前項目有過這樣的需求,然后就自己寫了一個類似的動畫,效果在下面:

自定義彈性動畫.gif注意

然后上面自定義彈性動畫的代碼在這里:

#import"UIView+ShakeAnimation.h"#importtypedefvoid(^RunAnimationBlock)();@interfaceUIView()@property(nonatomic,copy)RunAnimationBlock block;@end@implementationUIView(ShakeAnimation)-(void)startAnimationFromFrame:(CGRect)framef? ? ? ? ? ? ? ? ? ? ? toFrame:(CGRect)framet? ? ? ? ? ? ? ? ? ? ? duration:(CGFloat)duration? ? ? ? ? ? ? ? ? ? shakeTimes:(NSInteger)times? ? ? ? ? ? ? ? stretchPercent:(CGFloat)stretchPercent? ? ? ? ? ? ? ? ? ? completion:(void(^)(BOOLfinished))completion{self.layer.masksToBounds=YES;? ? __blockCGFloatperTime = duration / times;? ? __blockCGFloatperx = (framet.origin.x- framef.origin.x) * stretchPercent / times;? ? __blockCGFloatpery = (framet.origin.y- framef.origin.y) * stretchPercent / times;? ? __blockCGFloatperw = (framet.size.width- framef.size.width) * stretchPercent / times;? ? __blockCGFloatperh = (framet.size.height- framef.size.height) * stretchPercent / times;? ? __blockUIView* tmpView =self;? ? __blockNSIntegertmpTimes = (NSInteger)times;? ? __blockNSIntegertmpsymbol = -1;? ? __weaktypeof(self) weakSelf =self;self.block= ^{? ? ? ? [UIViewanimateWithDuration:perTime animations:^{CGFloatx = framet.origin.x+ perx * tmpTimes;CGFloaty = framet.origin.y+ pery * tmpTimes;CGFloatw = framet.size.width+ perw * tmpTimes;CGFloath = framet.size.height+ perh * tmpTimes;CGRectrect =CGRectMake(x, y, w, h);? ? ? ? ? ? tmpView.frame= rect;? ? ? ? }completion:^(BOOLfinished) {? ? ? ? ? ? tmpTimes = tmpTimes + tmpsymbol;? ? ? ? ? ? tmpTimes = - tmpTimes;? ? ? ? ? ? tmpsymbol = - tmpsymbol;if(tmpTimes !=0) {? ? ? ? ? ? ? ? weakSelf.block();? ? ? ? ? ? }else{? ? ? ? ? ? ? ? [UIViewanimateWithDuration:perTime animations:^{? ? ? ? ? ? ? ? ? ? tmpView.frame= framet;? ? ? ? ? ? ? ? }completion:^(BOOLfinished) {? ? ? ? ? ? ? ? ? ? completion(YES);? ? ? ? ? ? ? ? }];? ? ? ? ? ? }? ? ? ? }];? ? };self.block();}staticcharRunAnimationBlockKey;-(RunAnimationBlock)block{returnobjc_getAssociatedObject(self, &RunAnimationBlockKey);}-(void)setBlock:(RunAnimationBlock)block{? ? objc_setAssociatedObject(self, &RunAnimationBlockKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);}@end

調用:

[self.demoView2 startAnimationFromFrame:CGRectMake(10,300,100,100)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? toFrame:CGRectMake(10,300,300,100)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? duration:0.5shakeTimes:5stretchPercent:0.3completion:^(BOOL finished) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"======over======:%@",self.demoView1);? ? ? ? ? ? ? ? ? ? ? ? ? ? }];

上面兩個彈性動畫的代碼在這里:人口統計學彈性動畫

CAKeyframeAnimation關鍵幀動畫

CAKeyframeAnimation的屬性

//關鍵幀值數組,一組變化值@property(nullable,copy)NSArray*values;//關鍵幀幀路徑,優先級比values大@property(nullable)CGPathRefpath;//每一幀對應的時間,時間可以控制速度.它和每一個幀相對應,取值為0.0-1.0,不設則每一幀時間相等.@property(nullable,copy)NSArray *keyTimes;//每一幀對應的時間曲線函數,也就是每一幀的運動節奏@property(nullable,copy)NSArray *timingFunctions;//動畫的計算模式,默認值: kCAAnimationLinear.有以下幾個值://kCAAnimationLinear//關鍵幀為座標點的時候,關鍵幀之間直接直線相連進行插值計算;//kCAAnimationDiscrete//離散的,也就是沒有補間動畫//kCAAnimationPaced//平均,keyTimes跟timeFunctions失效//kCAAnimationCubic對關鍵幀為座標點的關鍵幀進行圓滑曲線相連后插值計算,對于曲線的形狀還可以通過tensionValues,continuityValues,biasValues來進行調整自定義,keyTimes跟timeFunctions失效//kCAAnimationCubicPaced在kCAAnimationCubic的基礎上使得動畫運行變得均勻,就是系統時間內運動的距離相同,,keyTimes跟timeFunctions失效@property(copy)NSString*calculationMode;//動畫的張力,當動畫為立方計算模式的時候此屬性提供了控制插值,因為每個關鍵幀都可能有張力所以連續性會有所偏差它的范圍為[-1,1].同樣是此作用@property(nullable,copy)NSArray *tensionValues;//動畫的連續性值@property(nullable,copy)NSArray *continuityValues;//動畫的偏斜率@property(nullable,copy)NSArray *biasValues;//動畫沿路徑旋轉方式,默認為nil.它有兩個值://kCAAnimationRotateAuto//自動旋轉,//kCAAnimationRotateAutoReverse//自動翻轉@property(nullable,copy)NSString*rotationMode;

CAKeyframeAnimation可以做很豐富的效果,下面展示了幾種純CAKeyframeAnimation做的效果:

CAKeyframeAnimation.gif

以上效果的代碼都比較簡單,量也比較大,這里就不貼出來了,這里可以下載:人口統計學關鍵幀動畫

CAAnimationGroup動畫組

CAAnimationGroup的屬性

//只有一個屬性,數組中接受CAAnimation元素@property(nullable,copy)NSArray *animations;

可以看到CAAnimationGroup只有一個屬性一個CAAnimation數組。而且它繼承于CAAnimation,它具有CAAnimation的特性,所以它的用法和CAAnimation是一樣的,不同的是他可以包含?個動畫,也就是說他可以接受很多個CAAnimation并且可以讓它們一起開始,這就造成了動畫效果的疊加,效果就是?個動畫同時進行。

來看一個簡單的效果:

CAAnimationGroup.gif

這個是動畫是,旋轉,抖動,透明度一起作用在一起的效果,代碼在這里人口統計學動畫組

CATransition轉場動畫

//轉場類型,字符串類型參數.系統提供了四中動畫形式://kCATransitionFade//逐漸消失//kCATransitionMoveIn//移進來//kCATransitionPush//推進來//kCATransitionReveal//揭開//另外,除了系統給的這幾種動畫效果,我們還可以使用系統私有的動畫效果://@"cube",//立方體翻轉效果//@"oglFlip",//翻轉效果//@"suckEffect",//收縮效果,動畫方向不可控//@"rippleEffect",//水滴波紋效果,動畫方向不可控//@"pageCurl",//向上翻頁效果//@"pageUnCurl",//向下翻頁效果//@"cameralIrisHollowOpen",//攝像頭打開效果,動畫方向不可控//@"cameraIrisHollowClose",//攝像頭關閉效果,動畫方向不可控@property(copy)NSString*type;//轉場方向,系統一共提供四個方向://kCATransitionFromRight//從右開始//kCATransitionFromLeft//從左開始//kCATransitionFromTop//從上開始//kCATransitionFromBottom//從下開始@property(nullable,copy)NSString*subtype;//開始進度,默認0.0.如果設置0.3,那么動畫將從動畫的0.3的部分開始@propertyfloatstartProgress;//結束進度,默認1.0.如果設置0.6,那么動畫將從動畫的0.6部分以后就會結束@propertyfloatendProgress;//開始進度@property(nullable,strong)idfilter;

CATransition也是繼承CAAnimation,系統默認提供了12種動畫樣式,加上4個動畫方向,除了方向不可控的四種效果外,大概一共提供了36種動畫。

另外系統還給UIView的添加了很多分類方法可以快速完成一些簡單的動畫,如下:

的UIView(UIViewAnimation)

@interfaceUIView(UIViewAnimation)+ (void)beginAnimations:(nullableNSString*)animationID context:(nullablevoid*)context;// additional context info passed to will start/did stop selectors. begin/commit can be nested//提交動畫+ (void)commitAnimations;//設置代理+ (void)setAnimationDelegate:(nullableid)delegate;//設置動畫開始方法+ (void)setAnimationWillStartSelector:(nullable SEL)selector;//設置動畫結束方法+ (void)setAnimationDidStopSelector:(nullable SEL)selector;//設置動畫時間:default = 0.2+ (void)setAnimationDuration:(NSTimeInterval)duration;//設置動畫延遲開始時間:default = 0.0+ (void)setAnimationDelay:(NSTimeInterval)delay;//設置動畫延遲開始日期:default = now ([NSDate date])+ (void)setAnimationStartDate:(NSDate*)startDate;//設置動畫運動曲線:default =UIViewAnimationCurveEaseInOut//UIViewAnimationCurveEaseInOut,//慢進慢出//UIViewAnimationCurveEaseIn, //慢進快出//UIViewAnimationCurveEaseOut,//快進慢出//UIViewAnimationCurveLinear//勻速+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;//設置重復次數: default = 0.0.? May be fractional+ (void)setAnimationRepeatCount:(float)repeatCount;//設置是否翻轉動畫: default = NO. used if repeat+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses;//設置動畫是否從當前狀態開始:default = NO+ (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState;//設置動畫類型+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView*)view cache:(BOOL)cache;//設置動畫是否有效+ (void)setAnimationsEnabled:(BOOL)enabled;//+ (BOOL)areAnimationsEnabled;//+ (void)performWithoutAnimation:(void(^)(void))actionsWithoutAnimation//+ (NSTimeInterval)inheritedAnimationDuration@end

的UIView(UIViewAnimationWithBlocks)

@interfaceUIView(UIViewAnimationWithBlocks)//以下方法都大同小異,就不一一做注釋了+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^ __nullable)(BOOLfinished))completion;+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void(^)(void))animations completion:(void(^ __nullable)(BOOLfinished))completion + (void)animateWithDuration:(NSTimeInterval)duration animations:(void(^)(void))animations;+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^ __nullable)(BOOLfinished))completion+ (void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^ __nullable)(void))animations completion:(void(^ __nullable)(BOOLfinished))completion;+ (void)transitionFromView:(UIView*)fromView toView:(UIView*)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void(^ __nullable)(BOOLfinished))completion;+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray<__kindofUIView*> *)views options:(UIViewAnimationOptions)options animations:(void(^ __nullable)(void))parallelAnimations completion:(void(^ __nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(7_0);@end

的UIView(UIViewKeyframeAnimations)

+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void(^)(void))animations completion:(void(^ __nullable)(BOOLfinished))completion;+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void(^)(void))animations

以上方法比較多,找值得說的簡單說一下吧:

//單視圖轉場動畫+ (void)transitionWithView:(UIView*)view? ? ? ? ? ? ? ? ? duration:(NSTimeInterval)duration? ? ? ? ? ? ? ? ? ? options:(UIViewAnimationOptions)options? ? ? ? ? ? ? ? animations:(void(^ __nullable)(void))animations? ? ? ? ? ? ? ? completion:(void(^ __nullable)(BOOLfinished))completion//雙視圖轉場動畫+ (void)transitionFromView:(UIView*)fromView? ? ? ? ? ? ? ? ? ? toView:(UIView*)toView? ? ? ? ? ? ? ? ? duration:(NSTimeInterval)duration? ? ? ? ? ? ? ? ? ? options:(UIViewAnimationOptions)options? ? ? ? ? ? ? completion:(void(^ __nullable)(BOOLfinished))completion

這兩個都是轉場動畫,不同的是第一個是單視圖轉場,第二個是雙視圖轉場不過需要注意的是:單視圖轉場動畫只能用作屬性動畫做不到的轉場效果,比如屬性動畫不能給的UIImageView的形象賦值操作做動畫效果等。

我們可以看到以上兩個方法中都有一個共同的參數:

UIViewAnimationOptions

typedefNS_OPTIONS(NSUInteger, UIViewAnimationOptions){? ? UIViewAnimationOptionLayoutSubviews? ? ? ? ? ? =1<<0,? ? UIViewAnimationOptionAllowUserInteraction? ? ? =1<<1,// turn on user interaction while animatingUIViewAnimationOptionBeginFromCurrentState? ? =1<<2,// start all views from current value, not initial valueUIViewAnimationOptionRepeat? ? ? ? ? ? ? ? ? ? =1<<3,// repeat animation indefinitelyUIViewAnimationOptionAutoreverse? ? ? ? ? ? ? =1<<4,// if repeat, run animation back and forthUIViewAnimationOptionOverrideInheritedDuration =1<<5,// ignore nested durationUIViewAnimationOptionOverrideInheritedCurve? ? =1<<6,// ignore nested curveUIViewAnimationOptionAllowAnimatedContent? ? ? =1<<7,// animate contents (applies to transitions only)UIViewAnimationOptionShowHideTransitionViews? =1<<8,// flip to/from hidden state instead of adding/removingUIViewAnimationOptionOverrideInheritedOptions? =1<<9,// do not inherit any options or animation typeUIViewAnimationOptionCurveEaseInOut? ? ? ? ? ? =0<<16,// defaultUIViewAnimationOptionCurveEaseIn? ? ? ? ? ? ? =1<<16,? ? UIViewAnimationOptionCurveEaseOut? ? ? ? ? ? ? =2<<16,? ? UIViewAnimationOptionCurveLinear? ? ? ? ? ? ? =3<<16,? ? UIViewAnimationOptionTransitionNone? ? ? ? ? ? =0<<20,// defaultUIViewAnimationOptionTransitionFlipFromLeft? ? =1<<20,? ? UIViewAnimationOptionTransitionFlipFromRight? =2<<20,? ? UIViewAnimationOptionTransitionCurlUp? ? ? ? ? =3<<20,? ? UIViewAnimationOptionTransitionCurlDown? ? ? ? =4<<20,? ? UIViewAnimationOptionTransitionCrossDissolve? =5<<20,? ? UIViewAnimationOptionTransitionFlipFromTop? ? =6<<20,? ? UIViewAnimationOptionTransitionFlipFromBottom? =7<<20,} NS_ENUM_AVAILABLE_IOS(4_0);

可以看到系統給到的是一個位移枚舉,這就意味著這個枚舉可以多個值同時使用,但是怎么用呢?其實那些枚舉值可以分為三個部分。

我們分別看一下每個枚舉的意思:

第一部分:動畫效果

UIViewAnimationOptionTransitionNone//沒有效果UIViewAnimationOptionTransitionFlipFromLeft//從左水平翻轉UIViewAnimationOptionTransitionFlipFromRight//從右水平翻轉UIViewAnimationOptionTransitionCurlUp//翻書上掀UIViewAnimationOptionTransitionCurlDown//翻書下蓋UIViewAnimationOptionTransitionCrossDissolve//融合UIViewAnimationOptionTransitionFlipFromTop//從上垂直翻轉? ? ? ? ? ? ? ? ? ? UIViewAnimationOptionTransitionFlipFromBottom//從下垂直翻轉

第二部分:動畫運動曲線

//開始慢,加速到中間,然后減慢到結束UIViewAnimationOptionCurveEaseInOut//開始慢,加速到結束UIViewAnimationOptionCurveEaseIn//開始快,減速到結束UIViewAnimationOptionCurveEaseOut//線性運動UIViewAnimationOptionCurveLinear

第三部分:其他

//默認,跟父類作為一個整體UIViewAnimationOptionLayoutSubviews//設置了這個,主線程可以接收點擊事件UIViewAnimationOptionAllowUserInteraction//從當前狀態開始動畫,父層動畫運動期間,開始子層動畫.UIViewAnimationOptionBeginFromCurrentState//重復執行動畫,從開始到結束, 結束后直接跳到開始態UIViewAnimationOptionRepeat//反向執行動畫,結束后會再從結束態->開始態UIViewAnimationOptionAutoreverse//忽略繼承自父層持續時間,使用自己持續時間(如果存在)UIViewAnimationOptionOverrideInheritedDuration//忽略繼承自父層的線性效果,使用自己的線性效果(如果存在)UIViewAnimationOptionOverrideInheritedCurve//允許同一個view的多個動畫同時進行UIViewAnimationOptionAllowAnimatedContent//視圖切換時直接隱藏舊視圖、顯示新視圖,而不是將舊視圖從父視圖移除(僅僅適用于轉場動畫)? ? ? ? ? ? UIViewAnimationOptionShowHideTransitionViews//不繼承父動畫設置或動畫類型.UIViewAnimationOptionOverrideInheritedOptions

這下可以看到,這些枚舉功能都不一樣但是可以隨意組合,但是組合的時候需要注意,類型同一枚舉的一起不能使用比如UIViewAnimationOptionCurveEaseIn狀語從句:UIViewAnimationOptionCurveEaseOut

然后我們看一下轉場動畫的一些效果:

單視圖轉場

單視圖轉場.gif注意

雙視圖轉場

雙視圖轉場.gif注意

CATransition視圖轉場

CATransition.gif

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容