現現在App的體驗愈來愈重要,咱們的App中也要求加入更多的動畫效果,其中最普遍的是轉場動畫,因爲須要批量的加入轉場動畫,若是於每個VC中去添加修改是一件費時費力的事情,因此有了下面要介紹的一個開源組件--WKAnimatorManagergit
實現了對轉場動畫的封裝以及左滑的集中處理。github
優勢:集成方便,使用簡單,拓展性強。bash
轉場管理結構中只有四個類:動畫
功能:hook了UINavigationController的部分方法,實現集成便可使用。 其一:hook了push,pop系列方法,於其中設置動畫轉場子類,便於統一處理動畫 其二:重寫了viewdidload 設置UINavigationController的轉場代理爲WKAnimatorManager的單例ui
功能:hook了UIViewController的部分方法以及新增了兩個屬性,實現集成便可使用。 其一:爲UIViewController添加了兩個轉場動畫屬性,一個用於模態轉場wk_modelAnimator,一個用於導航欄轉場wk_navAnimator,均爲WKBaseAnimator的子類 其二:hook了dismiss以及present模態轉場方法,便於統一處理動畫 其三:hook了init,講其模態轉場代理設置爲WKAnimatorManager單例atom
功能:遵循模態以及導航欄轉場協議,集中處理轉場邏輯 內部自定義了UIScreenEdgePanGestureRecognizer手勢,實現左滑返回邏輯自處理。spa
功能:動畫處理基類 自定義動畫只須要繼承自此類,將動畫效果寫於present以及dismiss方法便可。 如需左滑手勢返回,系統只支持了view層級動畫的左滑返回操做,因此左滑返回動畫必須爲view層級動畫,其次需設置edgeType爲UIRectEdgeLeft便可。代理
於Podfile中添加 pod 'WKAnimatorManager', '~> 0.1.1'code
下載Demo,將Demo裏的Transitions文件夾拖入項目,再將已整合好的頭文件WKAnimatorManagerHeader.h加入全局頭文件.pch中。cdn
建立繼承自WKBaseAnimator.h的自定義動畫類,下面以Demo中已存在的的動畫做爲例子(後面有效果展現):
#import "WKBaseAnimator.h"
@interface MagicMoveTransition : WKBaseAnimator
//自定義須要的屬性
@property (nonatomic, assign) CGRect endRect;//終點
@property (nonatomic, strong) UIView * sourceView;
@end
複製代碼
於.m文件中實現從父類繼承而來的present以及dismiss
- (void)present{
[UIView animateWithDuration:[self transitionDuration] delay:0.0f usingSpringWithDamping:0.8f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveLinear animations:^{
.....
} completion:^(BOOL finished) {
.....
//告訴系統動畫結束
[self completeTransition];
}];
}
- (void)dismiss {
.....
//發生動畫
[UIView animateWithDuration:[self transitionDuration] delay:0.0f usingSpringWithDamping:0.8f initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
.....
} completion:^(BOOL finished) {
.....
//告訴系統動畫結束
[self completeTransition];
}];
}
複製代碼
可自定義動畫執行時間
- (NSTimeInterval)transitionDuration{
return 0.6f;
}
複製代碼
支持左滑返回能夠這樣,在初始化時將其邊界type修改成left
- (instancetype)init
{
self = [super init];
if (self) {
self.edgeType = UIRectEdgeLeft;
}
return self;
}
複製代碼
在push 或者 present以前爲vc設置上對應的動畫
- (void)gotoWindoeModelVC
{
WindowModelVC * vc = [WindowModelVC new];
WKWindowedModelAnimator * animator = [WKWindowedModelAnimator new];
animator.toViewHeight = SCREEN_HEIGHT / 2.f;
// vc.wk_modelAnimator = animator;
// [self.navigationController presentViewController:vc animated:YES completion:nil];
//均可以啊
vc.wk_navAnimator = animator;
[self.navigationController pushViewController:vc animated:YES];
}
複製代碼
在Demo中提供了一些經常使用的轉場動畫的封裝,可直接使用。
更多自定義的效果,可參考WKAnimatorManager的Demo。
既然各位看到這了,再給你們分享一個小知識。
在我實現自定義側滑(UIScreenEdgePanGestureRecognizer)時,發現設置了其edges爲UIRectEdgeLeft時,手勢被觸發的時機並非在我進行側滑時,而是在全屏任何一個地方都會觸發這個手勢。這一度對我形成了困擾。
那麼從觸發手勢開始思考,手勢一開始於屏幕上觸發(硬件層面),實質在這個層面是不會也不該該去作任何判斷其手勢的合法性,而是直接傳遞到系統由軟件來判斷其合法性,那麼爲何我設置了UIRectEdgeLeft這個值以後,卻沒有達到預想的效果呢。帶着這個疑問,我去攔截了系統的側滑手勢,發現其也是全屏能夠被觸發,只是一開始是UIGestureRecognizerStatePossible狀態,而後若是其起始點超過50則變爲了UIGestureRecognizerStateFailed狀態,而小於等於50時則進入UIGestureRecognizerStateBegan狀態,開始執行手勢。
那麼接下來就簡單了,咱們只須要實現下面一個代理方法便可實現徹底和系統如出一轍的側滑手勢了。
//系統左滑返回x實現方式
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer == self.edgePan) {
UIScreenEdgePanGestureRecognizer * pan = (UIScreenEdgePanGestureRecognizer *)gestureRecognizer;
CGPoint point = [pan locationInView:self.edgePanVC.view];
return (point.x < 50);
}
return NO;
}
複製代碼