標籤:
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 TransitionSingletonM(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
示範結果:從右往左進入,接著往左出去
iOS:自訂模態動畫 --UIPresentationController