iOS-自定义交互式转场动画

自定义转场动画主要有以下步骤
  • 自定义导航栏
  • 自定义交互动画
  • 通过UIPercentDrivenInteractiveTransition协议实现交互
自定义导航栏

自定义导航栏需要遵守<UINavigationControllerDelegate>协议,该协议主要有两个协议方法:

// 该方法返回导航跳转时的动画,如果返回nil,则是系统默认的跳转动画,并且通过operation来判断当前执行push还是pop
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    return nil;
}
// 该方法返回自定义交互动画,只有实现该协议,才能在跳转时实现与用户交互
-(id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
    return nil;
}
自定义跳转动画

自定义跳转动画需要遵守<UIViewControllerAnimatedTransitioning>协议,该协议主要实现下面的方法:

// 该方法返回动画执行的时间,transitionContext由系统获取
-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.3;
}
// 通过该协议,获取跳转的两个VC
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    [self animateTransition:transitionContext fromVC:fromVC toVC:toVC fromView:fromVC.view toView:toVC.view];
}
// 这是模仿系统导航跳转的例子
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView{
    [[transitionContext containerView] addSubview:toView];
    if (_isPush) {
        [[transitionContext containerView] bringSubviewToFront:toView];
        toView.transform = CGAffineTransformMakeTranslation(-toView.bounds.size.width, 0);
    }
    else{
        [[transitionContext containerView] bringSubviewToFront:fromView];
    }
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        if (_isPush) {
            toView.transform = CGAffineTransformIdentity;
        }
        else{
            fromView.transform = CGAffineTransformMakeTranslation(-fromView.bounds.size.width, 0);
        }
    } completion:^(BOOL finished) {
        transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}
实现交互

自定义一个类,继承自UIPercentDrivenInteractiveTransition,它遵守<UIViewControllerInteractiveTransitioning>协议,我们可以告诉它当前转场动画进行的百分比,它再来更新动画的进度。转场动画进行的百分比可以通过手势来计算

// 在view上加入pan手势
UIPanGestureRecognizer *gesture = objc_getAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey));
    if (gesture) {
        [self.interactiveVC.view removeGestureRecognizer:gesture];
    }
    gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
    [self.interactiveVC.view addGestureRecognizer:gesture];
    objc_setAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey), gesture,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// 当pan手势移动,通过移动的距离来计算当前跳转动画需要完成的百分比,当手势结束时,判断动画完成的百分比。如果>50%,finishInteractiveTransition完成跳转动画;如果<50%,cancelInteractiveTransition取消动画,返回原样
case UIGestureRecognizerStateChanged:
        CGFloat fraction = point.x / [[UIScreen mainScreen] bounds].size.width;
        fraction = fminf(fmaxf(fraction, 0.0), 1.0);
        self.shouldComplete = (fraction > 0.5);
        [self updateInteractiveTransition:fraction];
    break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
        self.interactioning = NO;
        if (!self.shouldComplete || pan.state == UIGestureRecognizerStateCancelled) {
            [self cancelInteractiveTransition];
        }
        else {
            [self finishInteractiveTransition];
        }
    break;
最后附上Demo的地址https://github.com/cdcyd/CommonControlsCollection

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3045
来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

6608
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2667
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2615
来自专栏菩提树下的杨过

Flash/Flex学习笔记(23):运动学原理

先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class B...

25210
来自专栏魂祭心

原 canvas绘制clock

4024
来自专栏杨龙飞前端

scrollto 到指定位置

2494
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4798
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

3955
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2612

扫码关注云+社区