趁週末閒暇之餘,重新寫一下present和push的自定義動畫。 本來之前有寫過一個,因為沒有及時整理,到導致一時凌亂,找不到具體在哪了,提醒各位,平時要注意程式碼的整理和歸檔,不然到時候重複的程式碼寫了又寫,那就得不償失了。廢話不過說,先看下下面的效果:
原生的present是從底部向上彈出相應的檢視控制器,而push動畫,則是將檢視從右邊推出來進行展示,為了檢視展示的統一性,需要自定義轉場動畫,將present改成從右往左推出來展示,在dismiss的VC中需要增加一個左邊的手勢,以滿足側滑返回的效果。
首先需要主頁VC實現UIViewControllerTransitioningDelegate
這個代理中的2個方法
#pragma mark - UIViewControllerTransitioningDelegate
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
return [[YQPresentTransitionAnimated alloc] init];
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
return [[YQDismissTransitionAnimated alloc] init];
}
複製程式碼
將它的present動畫和dismiss動畫交給我們自定義的動畫來管理。
####present動畫的自定義####
1.建立一個類,繼承至NSObject
,並實現UIViewControllerAnimatedTransitioning
的代理;
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface YQPresentTransitionAnimated : NSObject<UIViewControllerAnimatedTransitioning>
@end
複製程式碼
2.實現代理的2個方法
//1.定義轉場動畫的時間
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 0.4;
}
//2.實現轉場動畫的動畫效果
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; //主頁VC
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; //present的VC
UIView *containerView = transitionContext.containerView; //轉場的容器檢視,動畫完成後,會消失
UIView *fromView;
UIView *toView;
if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {
fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
toView = [transitionContext viewForKey:UITransitionContextToViewKey];
} else {
fromView = fromViewController.view;
toView = toViewController.view;
}
//注意這個對應關係
BOOL isPresenting = (toViewController.presentingViewController == fromViewController);
CGRect fromFrame = [transitionContext initialFrameForViewController:fromViewController];
CGRect toFrame = [transitionContext finalFrameForViewController:toViewController];
if (isPresenting) {
fromView.frame = fromFrame;
toView.frame = CGRectOffset(toFrame, toFrame.size.width, 0);
}
if (isPresenting)
[containerView addSubview:toView];
NSTimeInterval transitionDuration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:transitionDuration animations:^{
if (isPresenting) {
toView.frame = toFrame;
fromView.frame = CGRectOffset(fromFrame, fromFrame.size.width * 0.3 * -1, 0);
}
} completion:^(BOOL finished) {
//固定寫法
BOOL wasCancelled = [transitionContext transitionWasCancelled];
if (wasCancelled)
[toView removeFromSuperview];
[transitionContext completeTransition:!wasCancelled];
}];
}
複製程式碼
3.將主頁VC的transitioningDelegate
設為自己,**【千萬注意】:**還需要將present的頁面的transitioningDelegate
設為自己(主頁VC)
####dismiss動畫的自定義#### 跟上面的present步驟一樣,只需將動畫效果換成相反的即可。
附上原始碼: github.com/GitterYang/…