带有向下滑动动画的自定义推送视图控制器

Posted

技术标签:

【中文标题】带有向下滑动动画的自定义推送视图控制器【英文标题】: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: 下拉动画只在第一次起作用,从第二次开始,布局呈现错误,我不知道为什么会发生这种情况。

我哪里错了?

【问题讨论】:

【参考方案1】:

你应该实现UIViewControllerAnimatedTransitioning。

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

    @interface ViewController : UIViewController <UINavigationControllerDelegate>
    

    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;
    
    

    创建您的自定义 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://***.com/a/25026102/2242359

我仍然强烈建议阅读部分或全部这些指南:http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/http://www.objc.io/issue-5/view-controller-transitions.htmlhttp://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];

【讨论】:

以上是关于带有向下滑动动画的自定义推送视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

创建自定义视图控制器动画

如何在 Swift 3 中加载/删除带有动画的自定义视图

带有完成块和属性的自定义 segue 转换

在 iOS 9 上使用 NavigationController 进行推送动画的自定义转换

如何根据objective-c中的滚动方向创建一个从UINavBar后面向下或向上滑动的自定义UIView?

带有自定义后退按钮的滑动手势冻结根视图控制器