您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>源码下载>通讯/手机编程>

iOS自定义转场动画例程与需要注意的问题

大小:0.3 MB 人气: 2017-09-26 需要积分:1

  OS提供了一些内置的转场类型。Navigation controllers用push和pop来有层次地导航信息,tab bar controllers用切换tabs来在各部分之间跳转,所有的视图控制器可以根据特定任务模态化地present和dismiss另一个视图控制器。

  API介绍

  每一个自定义转场涉及三个主要对象:

  from view controller (消失的那个)

  to view controller (出现的那个)

  一个动画控制器

  自定义转场和在自定义之前一样。对于push和pop,意味着调用UINavigationController的push-、pop-、或者set-方法来修改视图控制器的堆栈。对于切换tabs,意味着修改UITabBarController的selectedIndex或selectedViewController属性。对于modal,则意味着调用?[UIViewController presentViewController: animated: completion: ]或?[UIViewController dismissViewControllerAnimated: completion: ]。无论哪种情况,这个步骤都确定了“from view controller”和“to view controller”。

  使用一个自定义转场,你需要一个动画控制器。对我来说这是自定义动画转场中最令人困惑的部分,因为每种转场需要的动画控制器不同。下表展示了如何为每种转场提供动画控制器。记着,委托方法总是返回动画控制器。

  iOS自定义转场

  动画控制器可以是任何遵守UIViewControllerAnimatedTransitioning协议的对象。该协议声明了两个必须要实现的方法。一个提供了动画的时间,另一个执行了动画。这些方法调用时都传递一个上下文。上下文提供了入口来访问信息和你创建自定义转场需要的对象。以下是一些重点:

  from view controller

  to view controller

  两个视图控制器view的第一帧和最后一帧

  container view,根据这篇文档,“作为的转场中视图的父视图”

  重要:上下文还实现了-completeTransition:,你必须在你自定义转场结束时调用一次。

  这是关于自定义转场所有你需要知道的。让我们来看一些例子!

  例子

  所有这些例子都可以在GitHub找到,你可以克隆这些仓库,然后边往下看边试试这些例子。

  这三个例子都直接或子类化地使用了TWTExampleViewController。它只是设置了视图的背景颜色,同时使你能够通过点击任何地方来结束例子回到主菜单。

  轻弹push和pop

  在这个例子中,目标是让push和pop使用flip动画而不是标准的slide动画。一开始我建立一个navigation controller并把TWTPushExampleViewController的实例当作root。TWTPushExampleViewController添加了一个叫“Push”的右按钮到导航栏。点击它时,一个新的TWTPushExampleViewController的实例被压入navigation的堆栈:

  - (void)pushButtonTapped

  {

  TWTPushExampleViewController *viewController = [[TWTPushExampleViewController alloc] init];

  viewController.delegate = self.delegate;

  [self.navigationController pushViewController:viewController animated:YES];

  }

  navigation controller的设置发生在TWTExamplesListViewController(运行demo主菜单的视图控制器)。注意,它把自己置为navigation controller的委托:

  - (void)presentPushExample

  {

  TWTPushExampleViewController *viewController = [[TWTPushExampleViewController alloc] init];

  viewController.delegate = self;

  UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

  navigationController.delegate = self;

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

  }

  这意味着当navigation controller的转场即将开始时,TWTExamplesListViewController将收到委托信息,并有机会返回一个动画控制器。对于这种转场,我使用一个TWTSimpleAnimationController的实例,它是一个+[UIView transitionFromView: toView: duration: options: completion:]的封装:

  - (id)navigationController:(UINavigationController *)navigationController

  animationControllerForOperation:(UINavigationControllerOperation)operation

  fromViewController:(UIViewController *)fromVC

  toViewController:(UIViewController *)toVC

  {

  TWTSimpleAnimationController *animationController = [[TWTSimpleAnimationController alloc] init];

  animationController.duration = 0.5;

  animationController.options = ( operation == UINavigationControllerOperationPush

  ? UIViewAnimationOptionTransitionFlipFromRight

  : UIViewAnimationOptionTransitionFlipFromLeft);

  returnanimationController;

  }

  如果转场是一个push,我使用一个从右侧的flip,否则,我使用一个从左侧的flip。

  以下是TWTSimpleAnimationController的实现:

  - (NSTimeInterval)transitionDuration:(id)transitionContext

  {

  returnself.duration;

  }

  - (void)animateTransition:(id)transitionContext

  {

  UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

  UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

  toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];

  [toViewController.view layoutIfNeeded];

  [UIView transitionFromView:fromViewController.view

  toView:toViewController.view

  duration:self.duration

  options:self.options

  completion:^(BOOL finished) {

  [transitionContext completeTransition:YES];

  }];

  }

  记着,这两个方法是UIViewControllerAnimatedTransitioning协议的一部分。在动画控制器运行自定义转场的时候,它们被UIKit调用。

  这里有一些关于animateTransition:需要注意的事情:

  from view controller,to view controller,以及to view controller的最后一帧都从转场的上下文中提取。其中还有一些其他可提取的信息,但在当前情况下,并不需要所有信息。

  +[UIView transitionFromView: toView: duration: options: completion:]负责有层次地添加和删除视图。在后面的例子中,我将展示一种手动完成的情况。

  在转场的completion代码块中,我调用[transitionContext completeTransition: YES]来告诉系统转场结束了。如果你忘了这样做,你将无法与app交互。如果出现这种情况,先检查这个原因。

  以上就是全部!现在有一些值得尝试的东西:

  改变动画的持续时间来看看它如何影响navigation bar的动画。

  把动画选项由flip改为page curls。

  找一个方法让navigation的堆栈中的每个视图控制器能指定自己的动画控制器。看看在本文最后的推荐模式中提出的方法。

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!