iOS CAAnimation之CATransition (自定義轉場動畫工具類)
1.github原始碼:簡書作者wazrx
2.OC:轉場動畫的管理工具類(無互動)
3.swift: 轉場動畫的管理工具類(無互動)
oc 鏈式配置轉場動畫樣式 以及時間 配置
self.presentConfig
.setUpPresentStyle(presentStyle)
.setUpDismissStyle(dismissStyle)
.setUpPresentDuration(0.4)
.setUpDismissDuration(0.4)
.setUpIsLinkage(true);
modal 的view 的陰影設定
self.shadowAnimationConfig
.setUpDismissShadowColor([UIColor blueColor])
.setUpPresentShadowColor([UIColor blueColor])
.setUpPresentShadowOpacity(0.4)
.setUpDismissShadowOpacity(0.2)
.setUpDismissShadowOffset(CGSizeMake(1, 1))
.setUpPresentShadowOffset(CGSizeMake(-20, 10))
.setUpDismissShadowRadius(20)
.setUpPresentShadowRadius(30);
一、 參考資料:
1.王巍 《部落格》(非常詳細,推薦閱讀)
https://onevcat.com/2013/10/vc-transition-in-ios7/
2.xiao333ma 《部落格》
http://blog.csdn.net/xiao333ma/article/details/49028241#t1
3.VincentHK iOS 檢視控制器轉場詳解
工具pod 匯入
pod 'PYTransitionAnimater'
二、protocol
1.@protocol UIViewControllerContextTransitioning
- 這個介面用來提供切換上下文給開發者使用,包含了從哪個VC到哪個VC等各類資訊,一般不需要開發者自己實現。具體來說,iOS7的自定義切換目的之一就是切換相關程式碼解耦,在進行VC切換時,做切換效果實現的時候必須要需要切換前後VC的一些資訊。
- 重要的方法:
-(UIView *)containerView;
VC切換所發生的view容器,開發者應該將切出的view移除,將切入的view加入到該view容器中。
-(UIViewController *)viewControllerForKey:(NSString *)key;
提供一個key,返回對應的VC。現在的SDK中key的選擇只有:
UITransitionContextFromViewControllerKey表示將要切出VC。
UITransitionContextToViewControllerKey表示將要切入的VC。
-(CGRect)initialFrameForViewController:(UIViewController *)vc;
某個VC的初始位置,可以用來做動畫的計算。
-(CGRect)finalFrameForViewController:(UIViewController *)vc;
與上面的方法對應,得到切換結束時某個VC應在的frame。
-(void)completeTransition:(BOOL)didComplete;
向這個context報告切換已經完成。
2.@protocol UIViewControllerAnimatedTransitioning
- 這個介面負責切換的具體內容,也即“切換中應該發生什麼”。開發者在做自定義切換效果時大部分程式碼會是用來實現這個介面。
- 重要的方法:
-(NSTimeInterval)transitionDuration:(id < UIViewControllerContextTransitioning >)transitionContext;
系統給出一個切換上下文,我們根據上下文環境返回這個切換所需要的花費時間
(一般就返回動畫的時間就好了,SDK會用這個時間來在百分比驅動的切換中進行幀的計算)
-(void)animateTransition:(id < UIViewControllerContextTransitioning >)transitionContext;
在進行切換的時候將呼叫該方法,我們對於切換時的UIView的設定和動畫都在這個方法中完成。
3.@protocol UIViewControllerTransitioningDelegate
- 這個介面的作用比較簡單單一,在需要VC切換的時候系統會像實現了這個介面的物件詢問是否需要使用自定義的切換效果。
- 這個介面共有四個類似的方法:
前兩個方法是針對動畫切換的,我們需要分別在呈現VC和解散VC時,給出一個實現了UIViewControllerAnimatedTransitioning介面的物件(其中包含切換時長和如何切換)。後兩個方法涉及互動式切換
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForDismissedController:(UIViewController *)dismissed;
-(id< UIViewControllerInteractiveTransitioning >)interactionControllerForPresentation:(id < UIViewControllerAnimatedTransitioning >)animator;
-(id< UIViewControllerInteractiveTransitioning >)interactionControllerForDismissal:(id < UIViewControllerAnimatedTransitioning >)animator;
三、沒有互動的程式碼具體思想步驟
情景: VC_a跳到VC_b ,注意,轉場動畫不難,但是套路一定要明顯,我們都是有原則的人。戳這裡看原始碼
1. 建立VC_a
:VC_a
可以什麼都不用做,直接presen
2. 構建Animatr
轉場動畫的工具類(繼承NSObject
遵守<UIViewControllerTransitioningDelegate>
協議)
- 在
Animatr
中實現代理方法
//present
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForDismissedController:(UIViewController *)dismissed;
//dismiss
-(id<UIViewControllerAnimatedTransitioning>) animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
- 建立
AnimatedTransition
(繼承NSObject
遵守<UIViewControllerAnimatedTransitioning>
協議,在Animatr的方法中建立並返回)
- 你會發現,返回值需要遵守
UIViewControllerAnimatedTransitioning
協議的id型別的類
於是 建立AnimatedTransition
- 內部實現兩個方法
. 返回動畫時長
//1. 返回一個動畫時長,這個時長儘量要與實際動畫時長一直,因為系統會以此來作為轉場參考時間
-(NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
//2. 具體動畫的實現類
-(void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
self.transitionContext = transitionContext;
//1. 獲取到當前VC 目標VC
UIViewController * fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController * toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
//2. 獲取當前的容器檢視
UIView * contentView = [transitionContext containerView];
//3. 新增fromView,與toView(不能直接fromeVC.view獲取)
UIView *toView = [transitionContext viewForKey:(UITransitionContextToViewKey)];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
//[contentView addSubview:fromView];
[contentView addSubview:toView];
//4. contentView 設定蒙版 (這裡是灰色的蒙版)
contentView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.5];
//5. 動畫實現 分為present動畫和dismiss動畫 (可以在Animatr的代理方法中區分並傳進來)
if(present){
[UIView animateWithDuration:0.3 animations:^{
//這裡不能用toView.view獲取toView
}completion:^(BOOL finished) {
//注意:完成動畫要呼叫[transitionContext completeTransition:YES];告訴系統完成動畫了,否則就會造成toView不能相應點選的情況,可能在執行完動畫後,系統回到了主執行緒,一直在等待完成命令,所以沒有辦法執行點選事件
[transitionContext completeTransition:YES];
}];
}else if(dismiss){
[UIView animateWithDuration:0.3 animations:^{
//這時候,必須要用toVC.View獲取toView
} completion:^(BOOL finished) {
//注意:同present如果不告訴系統完成動畫了就會直接dismiss掉fromeVC不會有任何動畫,(這裡的dismiss只是把present時候的toVC與fromeVC顛倒了)
[transitionContext completeTransition:YES];
}];
}
}
-
VC_b
: 在init方法裡面設定delegate
和modalPresentationStyle
-(instancetype)init
{
self = [super init];
if (self) {
//這個屬性表示在modal、dismiss的時候會走自定義的方法
self.transitioningDelegate = self;
// 這個方法保證fromView才不會被移除(及可以在modal後看到a控制器的view)
self.modalPresentationStyle = UIModalPresentationCustom;
self.modalPresentationStyle = UIModalPresentationCustom;
}
return self;
}
四、有互動程式碼實現思路 —— 手勢驅動的百分比切換
1. 建立一個UIPercentDrivenInteractiveTransition 類
1.這是一個實現了UIViewControllerInteractiveTransitioning介面的類,為我們預先實現和提供了一系列便利的方法,可以用一個百分比來控制互動式切換的過程。一般來說我們更多地會使用某些手勢來完成互動式的轉移。
2. 本類中重要的方法
-(void)updateInteractiveTransition:(CGFloat)percentComplete;
//更新百分比,一般通過手勢識別的長度之類的來計算一個值,然後進行更新。
-(void)cancelInteractiveTransition ;
//報告互動取消,返回切換前的狀態
–(void)finishInteractiveTransition;
//報告互動完成,更新到切換後的狀態
3. 給view新增手勢(對於手勢的總結請看 iOS 手勢的基本介紹)
五、對於坑
1. dismiss轉場結束後出現黑屏:
參考:iOS 檢視控制器轉場詳解
Custom 模式:presentation 結束後,presentingView(fromView) 未被主動移出檢視結構,在 dismissal 中,注意不要像其他轉場中那樣將 presentingView(toView) 加入 containerView 中,否則 dismissal 結束後本來可見的 presentingView 將會隨著 containerView 一起被移除。如果你在 Custom 模式下沒有注意到這點,很容易出現黑屏之類的現象而不知道問題所在。
在 Custom 模式下的dismissal 轉場(在present中要新增)中不要像其他的轉場那樣將 toView(presentingView) 加入 containerView,否則 presentingView 將消失不見,而應用則也很可能假死。而 FullScreen 模式下可以使用與前面的容器類 VC 轉場同樣的程式碼。因此,上一節裡示範的 Slide 動畫控制器不適合在 Custom 模式下使用,放心好了,Demo 裡適配好了,具體的處理措施,請看下一節的處理
六、程式碼
1.github原始碼:簡書作者wazrx
2.OC:轉場動畫的管理工具類(無互動)
3.swift: 轉場動畫的管理工具類(無互動)
相關文章
- iOS自定義轉場動畫(push、pop動畫)iOS動畫
- 一行程式碼實現自定義轉場動畫--iOS自定義轉場動畫集行程動畫iOS
- iOS自定義轉場動畫實戰講解iOS動畫
- TransitionAnimation自定義轉場動畫NaN動畫
- 自定義轉場動畫(二)動畫
- 自定義轉場動畫(一)動畫
- iOS 關於viewController自定義的轉場動畫iOSViewController動畫
- 自定義present和dismiss的轉場動畫動畫
- iOS自定義UIView動畫效果iOSUIView動畫
- 自定義TabBar動畫效果 - 頁面轉場(Swift)tabBar動畫Swift
- iOS自定義 Transitions 動畫總結iOS動畫
- Flutter動畫之自定義動畫元件-FlutterLayoutFlutter動畫元件
- 關於自定義轉場動畫,我都告訴你。動畫
- 搞定動畫之 JQuery 中的自定義動畫動畫jQuery
- iOS偽轉場動畫iOS動畫
- 工具類——自定義Collections集合方法
- jQuery動畫—自定義動畫animate()jQuery動畫
- Android動畫效果之自定義ViewGroup新增布局動畫Android動畫View
- iOS專案開發實戰——配置自定義動畫iOS動畫
- 系統學習iOS動畫之四:檢視控制器的轉場動畫iOS動畫
- 自定義過渡動畫動畫
- 自定義動畫方法animate()動畫
- 自定義波紋動畫動畫
- 【Jquery】jquery 自定義動畫jQuery動畫
- [譯]Workcation App – 第一部分 . 自定義 Fragment 轉場動畫APPFragment動畫
- iOS CATransform3D的轉場動畫iOSORM3D動畫
- 就2小時教會你抽絲剝繭CAAnimation核心動畫之精美的下載動畫動畫
- Android SeekBar 自定義thumb,thumb旋轉動畫效果Android動畫
- iOS動畫專題·UIView二維形變動畫與CAAnimation核心動畫(transform動畫,基礎,關鍵幀,組動畫,路徑動畫,貝塞爾曲線)iOS動畫UIViewORM
- iOS自定義MJRefresh上拉和下拉重新整理動畫iOS動畫
- iOS自定義tabBariOStabBar
- 自定義Push/Pop和Present/Dismiss轉場
- iOS動畫系列之七:實現類似Twitter的啟動動畫iOS動畫
- iOS使用自定義URL實現控制器之間的跳轉iOS
- iOS系統導航欄自定義標題動畫跳變解析iOS動畫
- Java 給PPT新增動畫效果(預設動畫/自定義動畫)Java動畫
- java工具類之編碼轉換工具類Java
- 玩轉docker之自定義PHP容器DockerPHP