VCTransitionsLibrary –自定义iOS交互式转场动画的库

简介

VCTransitionsLibrary 提供了许多适用于入栈,出栈,模态等场景下控制器切换时的转场动画.它本身提供了一个定义好的转场动画库,你可以拖到自己工程中直接使用;也提供了许多拥有不同转场动画效果”互动控制器”,你可以直接使用这些控制器来和自定义动画效果配合使用;而不是自己控制去控制交互.

最新示例: 点击下载

注意: 自定义视图控制器的转场动画为iOS7 + 通过 UIViewControllerTransitioningDelegate协议, UINavigationControllerDelegate协议和 UITabBarControllerDelegate 协议提供的系统级别的支持.这个库的意义在于定义了常用的动画效果,并封装了常用的交互操作,简化了iOS交互式转场动画的编码量!

快速入门

运行环境

  • iOS 7+
  • ARC

安装

使用 CocoaPods 安装

pod "VCTransitionsLibrary"

手动安装

把文件 AnimationControllers 和 InteractionControllers 文件夹下所有代码复制到工程中即可.

使用

在自定义转场动画时,有两类关键的类:

  • 动画控制器 –  这个类是用来实现自定义动画的.但你声明想要使用自定义动画时,你应该提供一个动画控制器.这个类会实现需要的动画,完成时会通知框架.
  • 交互控制器 – 这个类是用来管理交互的-那些通常由某个手势空控制的交互,允许用户通过滑动,轻扫或执行其他操作来实现两个视图控制器的导航.必须指出的是,交互控制器允许导航取消,例如,一个用户可以在正在导航至某一页面时,突然改变主意,然后取消了操作.

注意: 动画和交互是完全独立的,这意味着你可以在其他任何自定义控制器上独立使用交互控制器-很酷!

使用动画控制器

AnimationControllers 文件夹中提供了许多可以整合进你的工程中的动画控制器:

自定义模态控制器显示/隐藏的动画

UIViewControllerTransitioningDelegate 协议被用来在模态控制器显示/隐藏时提供一个动画控制器.当一个视图控制器被模态显示或隐藏时,它的transitioningDelegate属性用来提供UIViewControllerTransitioningDelegate协议的支持.担当代理角色的类,通过 animationControllerForPresentedController: presentingController: sourceController: 方法返回模态显示时的动画, 通过 animationControllerForDismissedController: 返回模态消失时的动画即可.

自定义顶部导航的转场动画

UINavigationController 有一个

id<UINavigationControllerDelegate> delegate 属性.只需要让它的代理通过 navigationController: animationControllerForOperation: fromViewController: toViewController: 返回某个动画效果即可.

为了同时设置出栈/入栈都合适的动画效果(或者说,出栈/入栈时能使用相反方向的动画),你可以参考下面代码:

- (id<UIViewControllerAnimatedTransitioning>)navigationController:
                                (UINavigationController *)navigationController
   animationControllerForOperation:(UINavigationControllerOperation)operation
                fromViewController:(UIViewController *)fromVC
                  toViewController:(UIViewController *)toVC {

    // 出栈时,要反转动画方向.
    _animationController.reverse = operation == UINavigationControllerOperationPop;

    return _animationController;
}

自定义底部标签栏导航的转场动画

UITabBarController 有一个 id<UITabBarControllerDelegate> delegate属性,只需要让它的代理通过tabBarController: animationControllerForTransitionFromViewController: toViewController:返回某个动画效果即可.

为了给动画一个合适的方向,你可以比较两个视图控制器的索引:

- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
            animationControllerForTransitionFromViewController:(UIViewController *)fromVC
                                              toViewController:(UIViewController *)toVC {

    NSUInteger fromVCIndex = [tabBarController.viewControllers indexOfObject:fromVC];
    NSUInteger toVCIndex = [tabBarController.viewControllers indexOfObject:toVC];

    _animationController.reverse = fromVCIndex < toVCIndex;
    return _animationController;
}

使用交互控制器

交互控制器和动画控制器配合使用,可以实现交互式的动画转场效果,比如可以让用户通过手势来控制页面间的导航.交互控制器允许用户在一个转场动画中前进,后退,甚至退出.

交互控制器负责给视图添加手势,并负责在用户使用某个手势时进行相应地导航操作.

模态控制器消失时的交互

UIViewControllerTransitioningDelegate 协议,也用来提供对交互式转场的支持.下面是一个结合清扫手势和翻页动画的例子:

//实例变量,通常在你的初始化方法初始化它们
CEFlipAnimationController *_animationController;
CESwipeInteractionController *_interactionController;

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

    // 允许交互控制器绑定它的手势识别器.
    [_interactionController wireToViewController:presented 
                                    forOperation:CEInteractionOperationDismiss];
       _animationController.reverse = NO;
    return _animationController;
}

- (id<UIViewControllerAnimatedTransitioning>)
     animationControllerForDismissedController:(UIViewController *)dismissed {
    _animationController.reverse = YES;
    return _animationController;
}

- (id<UIViewControllerInteractiveTransitioning>)
           interactionControllerForDismissal:
                (id<UIViewControllerAnimatedTransitioning>)animator {

    // 如果有交互控制器被触发了,就直接使用它.返回nil,是为了支持用户通过点击某个按钮直接返回;此时不会触发交互控制器.
    return _interactionController.interactionInProgress
                ? _interactionController : nil;
}

出栈时的交互

UINavigationControllerDelegate 也有方法为交互式转场提供支持.一个典型的类似于上上面代码的模式:

// 实例变量,通常在你的初始化方法中初始化它们.
CEFlipAnimationController *_animationController;
CESwipeInteractionController *_interactionController;

- (id<UIViewControllerAnimatedTransitioning>)
                 navigationController:(UINavigationController *)navigationController
      animationControllerForOperation:(UINavigationControllerOperation)operation
                   fromViewController:(UIViewController *)fromVC
                     toViewController:(UIViewController *)toVC {

    // 把交互控制器绑定到你的视图控制器上.
    [_interactionController wireToViewController:toVC
                                    forOperation:CEInteractionOperationPop];

    _animationController.reverse = operation == UINavigationControllerOperationPop;

    return _animationController;
}

- (id <UIViewControllerInteractiveTransitioning>)
                         navigationController:(UINavigationController *)navigationController 
  interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>)animationController {

    //如果有交互控制器被触发了,就直接使用它.返回nil,是为了支持用户通过点击某个按钮直接返回;此时不会触发交互控制器. 
    return _interactionController.interactionInProgress
                ? _interactionController : nil;
}

用于标签栏控制器切换时的交互

UITabBarControllerDelegate 协议也为交互式转场提供了支持.但是由于代理方法在首次初始化时不被执行,所有需要其他方式来绑定交互控制器,如KVO:

@implementation TabBarViewController {
    CEFoldAnimationController *_animationController;
    CESwipeInteractionController *_swipeInteractionController;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        self.delegate = self;

        // 创建交互/动画控制器.
        _swipeInteractionController = [CESwipeInteractionController new];
        _animationController = [CEFoldAnimationController new];
        _animationController.folds = 3;

        // 使用观察者模式监测被选中的选择器的变化情况.
        [self addObserver:self
               forKeyPath:@"selectedViewController"
                  options:NSKeyValueObservingOptionNew
                  context:nil];
    }
    return self;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqualToString:@"selectedViewController"] )
    {
        // 把交互控制器绑定到视图控制器上.
        [_swipeInteractionController wireToViewController:self.selectedViewController
                                             forOperation:CEInteractionOperationTab];
    }
}



- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
            animationControllerForTransitionFromViewController:(UIViewController *)fromVC
                                              toViewController:(UIViewController *)toVC {

    NSUInteger fromVCIndex = [tabBarController.viewControllers indexOfObject:fromVC];
    NSUInteger toVCIndex = [tabBarController.viewControllers indexOfObject:toVC];

    _animationController.reverse = fromVCIndex < toVCIndex;
    return _animationController;
}

-(id<UIViewControllerInteractiveTransitioning>)tabBarController:(UITabBarController *)tabBarController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
    return _swipeInteractionController.interactionInProgress ? _swipeInteractionController : nil;
}

@end

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我和未来有约会

Silverlight初级教程-库

Silverlight初级教程 库 flash中有库这个概念。库里可以放很多的影片剪辑“MC”,一个MC可以在很多的地方使用,修改了库中的MC所有用到这个MC...

3739
来自专栏搞前端的李蚊子

基于Vue.js的大型报告页项目实现过程及问题总结(二)

距离上一篇文章过去了二十多天了,期间一直想把第二部分写完,结果在测试过程中遇到了各种坑爹的问题,到今天才算基本完成,也许还有后续,但趁着今天有时间就写出来吧,也...

41510
来自专栏前端说吧

JS-两周内自动登录功能

3619
来自专栏hotqin888的专栏

小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

741
来自专栏游戏杂谈

chrome、ff下flash的mousewheel事件失效(wmode=transparent)

1094
来自专栏编程微刊

微信小程序弹框提示绑定手环实例

今天想聊一聊小程序里面存在的一些逻辑问题,拿手上的这个小程序来说,(这个小程序是开发出来玩的,每个人手上有一个手环,带着手环时候的心率,运动步数,血压数据都会展...

881
来自专栏性能与架构

腾讯开源的非常小巧的JS手势库

腾讯前端团队前几天在Github上发布了一个JS手势库 AlloyFinger 极其小巧,只有几K,但功能很全面,支持缩放、旋转、拖拽、单击、双击、滑动、长按 ...

4105
来自专栏Java后端技术

欠的债,这一次都还给你们

  前段时间,写的一篇关于博客园主题皮肤分享的文章,一经发出便受到了极大的热捧,后来很多网友留言说,想要让我分享现在的模板,毕竟现在这个模板已经比之前分享的那个...

1123
来自专栏iOS开发攻城狮的集散地

iOS 自定义转场动画

1、创建一个遵循<UIViewControllerAnimatedTransitioning>协议的动画过渡管理对象,并实现如下两个方法:

2379
来自专栏iOS开发攻城狮的集散地

iOS 自定义转场动画

2845

扫码关注云+社区