iOS動畫
iOS有很多動畫技術,API主要分布在兩個庫中,一個是UIKit,另一個是CoreAnimation,先對UIKit動畫做一下總結。
UIKit動畫
在UIKit中,很多API都可以看到animated參數,表示是否動畫顯示,其實這是UIKit封裝CoreAnimation后的結果。
比如大家肯定都寫過模態視圖和導航控制器,他們在視圖展示的時候都會有一個animated參數。
[self.navigationController pushViewController:vc animated:YES];[self PResentViewController:vc animated:YES completion:nil];
這些動畫除了系統提供,其實我們是可以自己定制的,這里先簡單提一下,下面在詳細說。
主要API
UIKit主要API散落在UIView+UIViewAnimationWithBlocks和UIView+UIViewKeyframeAnimations兩個分類
@interface UIView(UIViewAnimationWithBlocks)+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))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 (^)(BOOL finished))completion + (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray *)views options:(UIViewAnimationOptions)options animations:(void (^)(void))parallelAnimations completion:(void (^)(BOOL finished))completion @end@interface UIView (UIViewKeyframeAnimations)+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0);@end
我們每個API挨著看一下
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
這個是動畫的一個常用API,用于創建常用的動畫,參數列表如下
參數 | 說明 |
duration | 持續時間 |
delay | 延時時間開始 |
options | 動畫選項(下面詳細解釋) |
animations | 動畫block |
completion | 動畫結束后的回調 |
下面我們看一個動畫例子:
[UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionAutoreverse animations:^{ CGRect frame = testView.frame; frame.origin.y += 100; testView.frame = frame; } completion:^(BOOL finished) { btn.hidden = YES; }];
這是在按鈕click事件里面的一段代碼,btn就是該按鈕,testView定義如下
testView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; testView.backgroundColor = [UIColor blackColor]; [self.view addSubview:testView];
大家運行代碼會發現,1秒后動畫開始,運行了0.5秒,視圖先向下再向上運動100回到原點,然后突然跳到100的位置按鈕消失。
回到原點的原因是我們options寫了UIViewAnimationOptionAutoreverse動畫選項,該項會在東環正向運行后自動翻轉動畫運行一遍。
大家應該能開出來options可以設置動畫的一些行為
options大體上可以分為三類,分為動畫屬性,動畫線性關系,和動畫轉場效果。
動畫屬性:
UIViewAnimationOptionLayoutSubviews | 在AutoLayout下,如果修改AutoLayout,那么子視圖也會跟著一起變化 |
UIViewAnimationOptionAllowUserInteraction | 在動畫時,允許用戶交互,比如按鈕在運動者還可以點擊 |
UIViewAnimationOptionBeginFromCurrentState | 從當前狀態開始動畫 |
UIViewAnimationOptionRepeat | 重復動畫 |
UIViewAnimationOptionAutoreverse | 動畫執行完畢自動翻轉 |
UIViewAnimationOptionOverrideInheritedDuration | 忽略外層動畫嵌套的執行時間 |
UIViewAnimationOptionOverrideInheritedCurve | 忽略外層動畫線性關系 |
動畫線性關系
UIViewAnimationOptionShowHideTransitionViews | 用顯隱的方式替代添加移除圖層的動畫效果 |
UIViewAnimationOptionOverrideInheritedOptions | 忽略嵌套繼承的選項 |
UIViewAnimationOptionCurveEaseInOut | 時間曲線函數,由慢到快 |
UIViewAnimationOptionCurveEaseIn | 時間曲線函數,由慢到特別快 |
UIViewAnimationOptionCurveEaSEOut | 時間曲線函數,由快到慢 |
UIViewAnimationOptionCurveLinear | 時間曲線函數,勻速 |
動畫轉場效果
UIViewAnimationOptionTransitionNone | 無轉場動畫 |
UIViewAnimationOptionTransitionFlipFromLeft | 轉場從左翻轉 |
UIViewAnimationOptionTransitionFlipFromRight | 轉場從右翻轉 |
UIViewAnimationOptionTransitionCurlUp | 上卷轉場 |
UIViewAnimationOptionTransitionCurlDown | 下卷轉場 |
UIViewAnimationOptionTransitionCrossDissolve | 轉場交叉消失 |
UIViewAnimationOptionTransitionFlipFromTop | 轉場從上翻轉 |
UIViewAnimationOptionTransitionFlipFromBottom | 轉場從下翻轉 |
轉場動畫
轉場動畫的API如下,是為了控制視圖的跳轉而使用的
[UIView transitionWithView:subView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ [subView addSubview:testView];} completion:^(BOOL finished) { }];
運行這段代碼可以看到視圖被翻轉過來的時候添加了testView在上面。
[UIView transitionFromView:subView toView:testView duration:1.0 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
這個方法可以控制一個控制器中的視圖切換。
關鍵幀動畫:
[UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{ [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.25 animations:^{ CGRect frame = testView.frame; frame.origin.y += 100 * flag; testView.frame = frame; }]; [UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.25 animations:^{ CGRect frame = testView.frame; frame.origin.y -= 100 * flag; testView.frame = frame; }]; [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{ CGRect frame = testView.frame; frame.origin.y += 200 * flag; testView.frame = frame; }]; } completion:^(BOOL finished) { btn.hidden = YES; }];
可以看到,關鍵幀動畫我們很方便的可以控制動畫的整個過程,addKeyframeWithRelativeStartTime:是添加關鍵幀方法,參數startTime是一個在0~1之間的數字,表示開始時間占總時間的%多少,比如上例中的第一幀就是0,第二針就是25%也就是在0.5秒開始。relativeDuration和開始時間一樣,是運行時間占整個時間的百分比。
彈簧動畫
[UIView animateWithDuration:0.5 delay:1.0 usingSpringWithDamping:1 initialSpringVelocity:0.1 options:UIViewAnimationOptionAutoreverse animations:^{ CGRect frame = testView.frame; frame.origin.y += 100 * flag; testView.frame = frame; } completion:^(BOOL finished) { btn.hidden = YES; }];
彈簧動畫的阻尼值,也就是相當于摩擦力的大小,該屬性的值從0.0到1.0之間,越靠近0,阻尼越小,彈動的幅度越大,反之阻尼越大,彈動的幅度越小,如果大道一定程度,會出現彈不動的情況。
彈簧動畫的速率,或者說是動力。值越小彈簧的動力越小,彈簧拉伸的幅度越小,反之動力越大,彈簧拉伸的幅度越大。這里需要注意的是,如果設置為0,表示忽略該屬性,由動畫持續時間和阻尼計算動畫的效果。
新聞熱點
疑難解答