iOS:自定義模態動畫 --UIPresentationController


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

演示結果:從右往左進入,接着往左出去

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM