美文网首页
合并展开弹出动画

合并展开弹出动画

作者: CoderLNHui | 来源:发表于2017-01-12 18:21 被阅读64次

    合并展开弹出动画

    效果图:

    70917765-21f2-4844-8f97-b87e9d4e018d.png

    要留的接口:

    1、外界设置跳转视图的Frame

    内部实现原理:

    • 1、完成UIViewControllerTransitioningDelegate的代理方法
    • 1.1、自定义frame,完成代理方法
    - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
    

    说明:需自定义UIPresentationController的子类,
    presentedFrame传递流程:
    外部控制器设置presentedFrame具体数值 -----> PopoverAnimator的代理方法中 ----> SHPresentationController设置

    • 1.2、自定义弹出和取消的动画
    • //自定义弹出的动画
    (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
    {
    
            return self;
    
    }
    
    • //自定义消失的动画
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
    
    {
    
           return self;
    
    }
    

    说明:
    如果要自定义弹出和消失的动画,需要遵守另一个代理UIViewControllerAnimatedTransitioning,包括动画的执行时间和具体的动画内容

    //动画执行的时间

    
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
    
    {
    
        return 0.5;
    
    }
    

    /// 获取转场的上下文:可以通过转场上下文获取弹出的View和消失的View

    
    // UITransitionContextFromViewKey : 获取消失的View
    
    // UITransitionContextToViewKey : 获取弹出的View
    
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
    
    {
    
    }
    

    外部调用接口:

    #import "ViewController.h"
    
    #import "PopoverViewController.h"
    
    #import "PopoverAnimator.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) PopoverAnimator *popoverAnimator;
    
    @end
    
    @implementation ViewController
    
    - (void)titleBtnClick:(TitleBtn *)titleBtn
    
    {
    
        // 1. 创建弹出控制器
    
        PopoverViewController *popoverVc = [[PopoverViewController alloc]init];
    
        // 2. 设置控制器的model样式
    
        popoverVc.modalPresentationStyle = UIModalPresentationCustom;
    
        // 3.设置转场的代理
    
        popoverVc.transitioningDelegate = self.popoverAnimator;
    
        self.popoverAnimator.presentedFrame = CGRectMake(0, 64, 375, 200);
    
        // 4.弹出控制器
    
        [self presentViewController:popoverVc animated:YES completion:nil];
    
    }
    

    OC代码实现:

    
    PopoverAnimator.h
    
    //
    
    //  PopoverAnimator.h
    
    //  DidClick(展开合并弹出动画)
    
    //
    
    //  Created by sunhui on 16/10/10.
    
    //  Copyright © 2016年 sunhui. All rights reserved.
    
    //
    
    #import <Foundation/Foundation.h>
    
    #import <UIKit/UIKit.h>
    
    typedef void(^PopoverAnimatorBlock)(BOOL ispresented);
    
    @interface PopoverAnimator : NSObject<UIViewControllerTransitioningDelegate>
    
    @property (nonatomic, assign) CGRect presentedFrame; // 弹出视图的frame
    
    @property (nonatomic, assign) BOOL isPresented;
    
    @property (nonatomic, copy) PopoverAnimatorBlock popAniBlock;
    
    - (instancetype)initWithPopoverAnimatorBlock:(PopoverAnimatorBlock)popAniBlock;
    
    /*
    
     presentedFrame传递流程:
    
     外部控制器设置presentedFrame具体数值 -----> PopoverAnimator的代理方法中 ----> SHPresentationController设置
    
     */
    
    @end
    
    
    PopoverAnimator.m
    
    //
    
    //  PopoverAnimator.m
    
    //  DidClick(展开合并弹出动画)
    
    //
    
    //  Created by sunhui on 16/10/10.
    
    //  Copyright © 2016年 sunhui. All rights reserved.
    
    //
    
    #import "PopoverAnimator.h"
    
    #import "SHPresentationController.h"
    
    @interface PopoverAnimator ()<UIViewControllerAnimatedTransitioning>
    
    @end
    
    
    @implementation PopoverAnimator 
    
    - (instancetype)initWithPopoverAnimatorBlock:(PopoverAnimatorBlock)popAniBlock
    
    {
    
        self = [super init];
    
        if (self) {
    
            self.isPresented = false;
    
            self.popAniBlock = popAniBlock;
    
        }
    
        return self;
    
    }
    
    #pragma mark - UIViewControllerTransitioningDelegate
    
    // 改变弹出View的尺寸
    
    - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
    
    {
    
        SHPresentationController *presentation = [[SHPresentationController alloc]initWithPresentedViewController:presented presentingViewController:presenting];
    
        presentation.presentedFrame = self.presentedFrame;
    
        return presentation;
    
    }
    
    //自定义弹出的动画
    
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
    
    {
    
        self.isPresented = YES;
    
        if (self.popAniBlock) {
    
            self.popAniBlock(self.isPresented);
    
        }
    
        return self;
    
    }
    
    //自定义消失的动画
    
    - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
    
    {
    
        self.isPresented = NO;
    
        if (self.popAniBlock) {
    
            self.popAniBlock(self.isPresented);
    
        }
    
        return self;
    
    }
    
    #pragma mark - UIViewControllerAnimatedTransitioning弹出和消失动画代理的方法
    
    //动画执行的时间
    
    - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
    
    {
    
        return 0.5;
    
    }
    
    /// 获取`转场的上下文`:可以通过转场上下文获取弹出的View和消失的View
    
    // UITransitionContextFromViewKey : 获取消失的View
    
    // UITransitionContextToViewKey : 获取弹出的View
    
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
    
    {
    
        self.isPresented ? [self animationForPresentedView:transitionContext] : [self animationForDismissedView:transitionContext];
    
    }
    
    #pragma mark - 自定义弹出动画和消失动画
    
    // 自定义弹出动画
    
    - (void)animationForPresentedView:(id<UIViewControllerContextTransitioning>)transitionContext
    
    {
    
        /// 1.获取弹出的View
    
        UIView *presentedView  = [transitionContext viewForKey:UITransitionContextToViewKey];
    
        // 2. 将弹出的View添加到ContainerView中
    
        [[transitionContext containerView] addSubview:presentedView];
    
        // 3.执行动画
    
        presentedView.transform = CGAffineTransformMakeScale(1.0, 0.0);
    
        //3.1、 更改锚点
    
        presentedView.layer.anchorPoint = CGPointMake(0.5, 0);
    
        
    
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
    
            
    
            presentedView.transform = CGAffineTransformIdentity;
    
        } completion:^(BOOL finished) {
    
            // 必须告诉转场上下文你已经完成动画
    
            [transitionContext completeTransition:YES];
    
        }];
    
        
    
    }
    
    // 自定义消失动画
    
    - (void)animationForDismissedView:(id<UIViewControllerContextTransitioning>)transitionContext
    
    {
    
        // 1.获取消失的View
    
        UIView *dismissView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    
        // 2.执行动画
    
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
    
            // 之所以设置为0.00001,算是xocde的bug,设置为0的话就没有动画效果了
    
            dismissView.transform = CGAffineTransformMakeScale(1.0, 0.00001);
    
        } completion:^(BOOL finished) {
    
            [dismissView removeFromSuperview];
    
            
    
            [transitionContext completeTransition:YES];
    
            
    
        }];
    
    }
    
    @end
    
    
    SHPresentationController.h
    //
    
    //  SHPresentationController.h
    
    //  DidClick(展开合并弹出动画)
    
    //
    
    //  Created by sunhui on 16/10/10.
    
    //  Copyright © 2016年 sunhui. All rights reserved.
    
    //  作用:设置弹出视图的frame
    
    #import <UIKit/UIKit.h>
    
    @interface SHPresentationController : UIPresentationController
    
    @property (nonatomic, assign) CGRect presentedFrame; // 弹出视图的frame
    
    @end
    
    
    SHPresentationController.m
    //
    
    //  SHPresentationController.m
    
    //  DidClick(展开合并弹出动画)
    
    //
    
    //  Created by sunhui on 16/10/10.
    
    //  Copyright © 2016年 sunhui. All rights reserved.
    
    //
    
    #import "SHPresentationController.h"
    
    @interface SHPresentationController ()
    
    @property (nonatomic, strong) UIView *coverView;
    
    @end
    
    
    @implementation SHPresentationController
    
    #pragma mark - 系统回调函数
    
    - (void)containerViewWillLayoutSubviews
    
    {
    
        [super containerViewWillLayoutSubviews];
    
        // 1.设置弹出View的尺寸
    
        self.presentedView.frame = self.presentedFrame;
    
        // 2.添加蒙版
    
        [self setupCoverView];
    
    }
    
    #pragma 添加蒙版
    
    - (void)setupCoverView
    
    {
    
        // 1、添加蒙版
    
        [self.containerView insertSubview:self.coverView atIndex:0];
    
        // 2、设置蒙版的属性
    
        
    
        // 3、添加手势
    
        UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(coverViewClick)];
    
        [self.coverView addGestureRecognizer:tapGes];
    
        
    
    }
    
    #pragma mark - coverViewClick
    
    - (void)coverViewClick
    
    {
    
        [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
    
    }
    
    #pragma mark - Getters
    
    - (UIView *)coverView
    
    {
    
        if (!_coverView) {
    
            _coverView = [[UIView alloc]init];
    
            _coverView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.2];
    
            _coverView.frame = self.containerView.bounds;
    
        }
    
        return _coverView;
    
    }
    
    @end
    
    点击上下箭头切换按钮:
    
    - (instancetype)initWithFrame:(CGRect)frame
    
    {
    
        self = [super initWithFrame:frame];
    
        if (self) {
    
            [self setImage:[UIImage imageNamed:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
    
            [self setImage:[UIImage imageNamed:@"navigationbar_arrow_down"] forState:UIControlStateSelected];
    
            [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    
            [self sizeToFit];
    
        }
    
        return self;
    
    }
    
    - (void)layoutSubviews
    
    {
    
        [super layoutSubviews];
    
        
    
        CGRect titleLabelF = self.titleLabel.frame;
    
        titleLabelF.origin.x = 0;
    
        self.titleLabel.frame = titleLabelF;
    
        
    
        CGRect imageViewF = self.imageView.frame;
    
        imageViewF.origin.x = self.titleLabel.frame.size.width + 5;
    
        self.imageView.frame = imageViewF;
    
        
    
    }
    

    相关文章

      网友评论

          本文标题:合并展开弹出动画

          本文链接:https://www.haomeiwen.com/subject/otndbttx.html