dismiss ios pop效果_iOS自定义转场动画-present和dismiss

本文介绍了如何在iOS中实现自定义的present和dismiss转场动画,包括使用UIViewControllerTransitioningDelegate协议指定动画控制器,实现动画效果,以及如何创建可交互的dismiss转场动画。
摘要由CSDN通过智能技术生成

自定义present、dismiss转场动画的步骤和自定义push、pop转场动画的步骤是一致的,相关内容请看《iOS自定义转场动画-push和pop》。

主要涉及的API

push和pop自定义转场动画通过导航控制器的UINavigationControllerDelegate配置,而present和dismiss自定义转场动画通过控制器的本身属性transitioningDelegate(UIViewControllerTransitioningDelegate)配置。

下面是要用到UIViewControllerTransitioningDelegate的几个方法:

//指定present动画

- (nullable id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;

//指定dismiss动画

- (nullable id )animationControllerForDismissedController:(UIViewController *)dismissed;

//指定交互式present动画的控制类

- (nullable id )interactionControllerForPresentation:(id )animator;

//指定交互式dismiss动画的控制类

- (nullable id )interactionControllerForDismissal:(id )animator;

present转场动画

1、准备工作:

ViewController类,要present到的下一级控制器SecondViewController类。

2、实现present动画:

这里演示的动画类似原生的push和pop动画,present时界面由右向左覆盖上一级界面,dismiss相反过程。

HSLeftPresentAnimation类定义:

@interface HSLeftPresentAnimation : NSObject

@property (nonatomic, assign) BOOL isPresent;

@end

为了方便我们将present和dismiss动画写在一起,通过属性isPresent设置动画类型。

@implementation HSLeftPresentAnimation

- (NSTimeInterval)transitionDuration:(id)transitionContext{

return 1.f;

}

- (void)animateTransition:(id)transitionContext{

UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

UIView* toView = nil;

UIView* fromView = nil;

UIView* transView = nil;

if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {

fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];

toView = [transitionContext viewForKey:UITransitionContextToViewKey];

} else {

fromView = fromViewController.view;

toView = toViewController.view;

}

if (_isPresent) {

transView = toView;

[[transitionContext containerView] addSubview:toView];

}else {

transView = fromView;

[[transitionContext containerView] insertSubview:toView belowSubview:fromView];

}

CGFloat width = [UIScreen mainScreen].bounds.size.width;

CGFloat height = [UIScreen mainScreen].bounds.size.height;

transView.frame = CGRectMake(_isPresent ?width :0, 0, width, height);

[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{

transView.frame = CGRectMake(_isPresent ?0 :width, 0, width, height);

} completion:^(BOOL finished) {

[transitionContext completeTransition:!transitionContext.transitionWasCancelled];

}];

}

@end

3、指定present要使用的转场动画行为:present转场的动画行为是由UIViewControllerTransitioningDelegate协议指定,所以我们设置secondVC的transitioningDelegate属性:

SecondViewController * secondVC = [[SecondViewController alloc] init];

secondVC.transitioningDelegate = self;

[self presentViewController:secondVC animated:YES completion:nil];

实现以下协议,指定动画类:

- (id)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{

HSLeftPresentAnimation* leftPresentAnimation = [[HSLeftPresentAnimation alloc] init];

leftPresentAnimation.isPresent = YES;

return leftPresentAnimation;

}

这样present转场动画就完成了,效果图如下:

present转场动画

dimiss转场动画

自定义dimiss转场动画和present动画步骤一样,在SecondViewController类里面指定transitioningDelegate,并实现协议方法即可。

- (void)viewDidAppear:(BOOL)animated{

[super viewDidAppear:animated];

self.transitioningDelegate = self;

}

- (id)animationControllerForDismissedController:(UIViewController *)dismissed{

HSLeftPresentAnimation* leftPresentAnimation = [[HSLeftPresentAnimation alloc] init];

leftPresentAnimation.isPresent = NO;

return leftPresentAnimation;

}

dimiss转场动画效果图:

dimiss转场动画效果图

dismiss变为可交互转场动画

现在我们也希望通过向右拖拽界面将界面dismiss掉,上一篇文章有说到可交互转场通过实现UIViewControllerInteractiveTransitioning的协议的类控制,官方为我们提供了一个通过百分比控制交互转场动画的类UIPercentDrivenInteractiveTransition。那么我们就使用它将dismiss变为可交互转场动画。

1、在SecondViewController里面添加手势

//添加手势

UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] init];

[pan addTarget:self action:@selector(panGestureRecognizerAction:)];

[self.view addGestureRecognizer:pan];

2、添加手势处理代码:

- (void)panGestureRecognizerAction:(UIPanGestureRecognizer *)pan{

//产生百分比

CGFloat process = [pan translationInView:self.view].x / ([UIScreen mainScreen].bounds.size.width);

process = MIN(1.0,(MAX(0.0, process)));

if (pan.state == UIGestureRecognizerStateBegan) {

self.interactiveTransition = [UIPercentDrivenInteractiveTransition new];

//触发dismiss转场动画

[self dismissViewControllerAnimated:YES completion:nil];

}else if (pan.state == UIGestureRecognizerStateChanged){

[self.interactiveTransition updateInteractiveTransition:process];

}else if (pan.state == UIGestureRecognizerStateEnded

|| pan.state == UIGestureRecognizerStateCancelled){

if (process > 0.5) {

[ self.interactiveTransition finishInteractiveTransition];

}else{

[ self.interactiveTransition cancelInteractiveTransition];

}

self.interactiveTransition = nil;

}

}

这里和pop手势处理一模一样只是更换了触发dismiss转场动画的代码。

3、通过UIViewControllerTransitioningDelegate指定交互动画的控制类

-(id)interactionControllerForDismissal:(id)animator{

return self.interactiveTransition;

}

现在基本完成了可交互的dismiss转场动画:

可交互的dismiss转场动画

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值