【问题标题】:Custom push view controller with slide down animation带有向下滑动动画的自定义推送视图控制器
【发布时间】:2015-04-07 17:11:55
【问题描述】:

我想自定义推送和弹出视图控制器,使用下拉/上拉动画,如下所示:

我尝试更改 y 位置,但它不起作用(根本不显示动画)。

  [self.navigationController pushViewController:nextController animated:NO];

  self.view.frame = CGRectMake(self.view.frame.origin.x,   self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
  [UIView animateWithDuration:0.6 animations:^{
   self.view.frame = CGRectMake(0, -self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height);
} completion:nil];

有什么建议吗?
P/s:在这种情况下我必须使用推送视图控制器而不是presentViewController

更新
我尝试像这样使用 UINavigationControllerDelegate:
PropertyViewController.h

@interface PropertyViewController : UIViewController <UINavigationControllerDelegate>{

}

PropertyViewController.m

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
  NSLog(@"willShowViewController");
}
 - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
NSLog(@"didShowViewController");
}

 -(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
  
  // THIS METHOD IS NOT CALLED AT ALL
  NSLog(@"animationControllerForOperation");
  TLTransitionAnimator *animator = [TLTransitionAnimator new];
  animator.presenting = (operation == UINavigationControllerOperationPush);
   animator.duration = 0.5;
   return animator;
 }

 - (void)viewGallery{
   // PUSH VIEW CONTROLLER
   GalleryViewController* galleryController = [[GalleryViewController alloc] initWithNibName:@"GalleryViewController" bundle:nil]; 
   galleryController.navigationController.delegate = self; 
   [self.navigationController pushViewController:galleryController animated:YES];
 }

更新 2
修复 PropertyViewController.m

中未使用此行调用的问题方法后
  self.navigationController.delegate = self;

我面临另一个问题。
push 时的向下滑动动画确实有效,但向上滑动无效。
这是我的自定义动画:

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

[[transitionContext containerView] addSubview:toViewController.view];
if (self.presenting) { // push
    fromViewController.view.transform = CGAffineTransformIdentity;
    toViewController.view.transform = CGAffineTransformMakeTranslation(0, toViewController.view.frame.size.height);
}else{ // pop
    fromViewController.view.transform = CGAffineTransformMakeTranslation(0, fromViewController.view.frame.size.height);
}

[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
    if (self.presenting) { // push
        fromViewController.view.transform = CGAffineTransformMakeTranslation(0, toViewController.view.frame.size.height);
        toViewController.view.transform = CGAffineTransformMakeTranslation(0, toViewController.view.frame.size.height);
    } else { // pop
        fromViewController.view.transform = CGAffineTransformMakeTranslation(0, 0);
    }
} completion:^(BOOL finished) {
    toViewController.view.transform = CGAffineTransformIdentity;
    
    [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}

问题2
下拉动画只在第一次起作用,从第二次开始,布局呈现错误,我不知道为什么会发生这种情况。

我哪里错了?

【问题讨论】:

    标签: ios objective-c uiviewcontroller


    【解决方案1】:

    你应该实现UIViewControllerAnimatedTransitioning

    1. 使您的FromViewController.m 符合UINavigationControllerDelegate。其他示例代码告诉您遵守UIViewControllerTransitioningDelegate,但前提是您呈现 ToViewController。

      @interface ViewController : UIViewController <UINavigationControllerDelegate>
      
    2. FromViewController 的委托回调方法中返回您的自定义过渡动画对象:

      - (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                     animationControllerForOperation:(UINavigationControllerOperation)operation
                                                  fromViewController:(UIViewController *)fromVC
                                                    toViewController:(UIViewController *)toVC {
          TransitionAnimator *animator = [TransitionAnimator new];
          animator.presenting = (operation == UINavigationControllerOperationPush);
          return animator;
      }
      
    3. 创建您的自定义 TransitionAnimator 动画师类并粘贴这些示例方法:

      - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
          return 0.5f;
      }
      
      - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
      {
          UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
          UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
          [[transitionContext containerView] addSubview:toViewController.view];
      
          if (self.presenting) {
              toViewController.view.transform = CGAffineTransformMakeTranslation(0, toViewController.view.frame.size.height);
          }
      
          [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
              if (self.presenting) {
                  toViewController.view.transform = CGAffineTransformIdentity;
              } else {
                  fromViewController.view.transform = CGAffineTransformMakeTranslation(0, toViewController.view.frame.size.height);
              }
          } completion:^(BOOL finished) {
              [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
          }];
      
      }
      

    大部分实现都来自这里,我只是根据您的需要编辑了转换方法:https://stackoverflow.com/a/25026102/2242359

    我仍然强烈建议阅读部分或全部这些指南:
    http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/
    http://www.objc.io/issue-5/view-controller-transitions.html
    http://objectivetoast.com/2014/03/17/custom-transitions-on-ios/

    【讨论】:

    • 谢谢,我使用 xib 文件加载视图控制器,我必须使用推送视图控制器而不是 presentViewController,所以我不知道在这种情况下如何应用 UIViewControllerAnimatedTransitioning。你能解释得更详细些吗?
    • 我更新了我的问题。问题是没有调用方法navigationController: animationControllerForOperation。而且我不知道我的问题出在哪里。
    • 推送GalleryViewController 时,应设置self.navigationController.delegate = self; 而不是galleryController.navigationController.delegate = self;
    • 谢谢,我的错,这个方法现在有效。我刚刚更新了我的问题。我需要用你的答案改变一些东西来使推送动画工作,但是弹出动画(从画廊拉起)仍然没有效果(弹出视图控制器时没有任何反应)。你有什么建议吗?
    【解决方案2】:

    试试这个:

    UIViewController *yourViewController = [[UIViewController alloc]init];
    
    [UIView  beginAnimations: @"Showinfo"context: nil];
    [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.75];
    [self.navigationController pushViewController: yourViewController animated:NO];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
    [UIView commitAnimations];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-21
      • 1970-01-01
      • 2016-08-10
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      相关资源
      最近更新 更多