UIPresentationController :展示控制器,是iOS8的一個新特性,用來展示模態窗口的。它是所有模態控制器的管理者。
即:
1> 管理所有Modal出來的控制器
2> 管理所有通過- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion方法顯示出來的控制器
3> 管理\監聽切換控制器的過程
4> presentingViewController:后面的控制器
5> presentedViewController:前面的控制器
6> presentedView:前面的控制器的view
注意:
1.只要調用了[self presentViewController: animated: completion:]方法
2.首先會創建一個UIPresentationController
3.然后由UIPresentationController管理控制器的切換
拓展:
1、系統給定的集中模態動畫展示樣式modalPresentationStyle有如下幾種:
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
UIModalPresentationFullScreen = 0,
UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2),
UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2),
UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),
UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0),
UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0),
UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0),
UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0),
UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1,
};
2、系統給定的集中模態動畫過渡樣式modalTransstionStyle有如下幾種:
typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2),
};
由於給定的東西畢竟有限,有的時候不能滿足自己需要的動畫效果,此時我們可以自己自定義modal動畫,做出炫目的動畫。
過程:其實做自定義的modal動畫還是比較復雜的,因為我既需要自定義動畫展示樣式類,也需要自定義動畫過渡樣式類,並且要實現這兩個類對應的協議,設置過渡代理,然后實現協議方法。
下面就是具體的實例,自定義modal動畫:
導入必要的第三方源文件,方便后面代碼的復用
在故事板中設置ViewController控制器的視圖顏色
創建一個secondViewController.h/.m/.xib文件,設置視圖顏色
創建自定義的動畫展示樣式類CustomPresentationController.h/.m文件,直接繼承自UIPresentationController
.h文件:
#import <UIKit/UIKit.h> @interface CustomPresentationController : UIPresentationController @end
.m文件:重寫下面的幾個方法
#import "CustomPresentationController.h" @implementation CustomPresentationController //可以改變被模態的控制器視圖的尺寸 //- (CGRect)frameOfPresentedViewInContainerView //{ // // /** containerView是容納presentedView的一個容器 */ // //return CGRectMake(0,50,self.containerView.frame.size.width,self.containerView.frame.size.height-100); // // return CGRectInset(self.containerView.bounds, 0, 50); //} //過渡即將開始時的處理 - (void)presentationTransitionWillBegin { self.presentedView.frame = self.containerView.frame; [self.containerView addSubview:self.presentedView]; } - (void)presentationTransitionDidEnd:(BOOL)completed { } - (void)dismissalTransitionWillBegin { } //過渡消失時的處理 - (void)dismissalTransitionDidEnd:(BOOL)completed { [self.presentedView removeFromSuperview]; } @end
創建自定義的動畫過渡樣式類CustomAnimationTransition.h/.m文件,實現UIViewControllerAnimatedTransitioning協議
.h文件:
#import <UIKit/UIKit.h> @interface CustomAnimationTransition : NSObject<UIViewControllerAnimatedTransitioning> @property (assign,nonatomic)BOOL presented; @end
.m文件:主要實現下面這兩個方法來設置自己需要的動畫過渡
#import "CustomAnimationTransition.h" #import "UIView+Extension.h" const CGFloat duration = 1.0f; @implementation CustomAnimationTransition #pragma mark -<UIViewControllerAnimatedTransitioning> //動畫時間 - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { return duration; } //設置過渡動畫(modal和dismiss的動畫都需要在這里處理) - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { // UITransitionContextToViewKey, // UITransitionContextFromViewKey. //出來的動畫 if (self.presented) { UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey]; //toView.y = -toView.height; //設置動畫從上往下進來 toView.x = toView.width; //設置動畫從右往左進來 //設置動畫3D旋轉 //toView.layer.transform = CATransform3DMakeRotation(M_PI_2, 1, 1, 0); [UIView animateWithDuration:duration animations:^{ //toView.y = 0; toView.x = 0; //toView.layer.transform = CATransform3DIdentity; } completion:^(BOOL finished) { //動畫完成后,視圖上的事件才能處理 [transitionContext completeTransition:YES]; }]; } //銷毀的動畫 else { [UIView animateWithDuration:duration animations:^{ UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; //fromView.y = -fromView.height; fromView.x = -fromView.width; //從右往左出去 //fromView.layer.transform = CATransform3DMakeRotation(M_PI_2, 1, 1, 0); } completion:^(BOOL finished) { //動畫完成后,視圖上的事件才能處理 [transitionContext completeTransition:YES]; }]; } } @end
創建一個單例的動畫類,將ViewController控制器類中實現的UIViewControllerTransitionDelegate協議的方法全部在該類Transition.m文件中實現,主控制器只需要創建這個單例類對象並將它設置為代理即可。
.h文件:
#import <UIKit/UIKit.h> #import "Singleton.h" @interface Transition : NSObject<UIViewControllerTransitioningDelegate> SingletonH(Transition); @end
.m文件:返回動畫展示樣式和動畫過渡樣式
#import "Transition.h" #import "CustomPresentationController.h" #import "CustomAnimationTransition.h" @implementation Transition SingletonM(Transition); #pragma mark - <UIViewControllerTransitioningDelegate> //返回展示樣式 -(UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source { return [[CustomPresentationController alloc]initWithPresentedViewController:presented presentingViewController:presenting]; } //展示的動畫 - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { CustomAnimationTransition *animation = [[CustomAnimationTransition alloc]init]; animation.presented = YES; return animation; } //關閉時的動畫 - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { CustomAnimationTransition *animation = [[CustomAnimationTransition alloc]init]; animation.presented = NO; return animation; } @end
在ViewController的.m文件中實現動畫測試如下:
#import "ViewController.h" #import "SecondViewController.h" #import "UIView+Extension.h" #import "Transition.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { SecondViewController *second = [[SecondViewController alloc]init]; //設置展示樣式(自定義) second.modalPresentationStyle = UIModalPresentationCustom;//設置過渡代理(UIPresentationController) second.transitioningDelegate = [Transition sharedTransition]; [self presentViewController:second animated:YES completion:nil]; } @end
演示結果:從右往左進入,接着往左出去