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

合并展开弹出动画

作者: 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