【问题标题】:Custom unwind segue animation自定义展开转场动画
【发布时间】:2014-08-23 05:13:04
【问题描述】:

我有以下设置:

红色控制器有方法

- (IBAction)unwindToRed:(UISegue *)segue

还有一个

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier

返回此事件的自定义转场。

在我的自定义 segue 中,我在执行代码中有以下内容:

- (void)perform
{
    // Just helpers to get the controllers from the segue
    UIViewController *destination = self.destinationViewController;
    UIViewController *source = self.sourceViewController;

    // Setting transitioning delegate for custom transitions
    destination.transitioningDelegate = self;
    source.transitioningDelegate = self;

    destination.modalTransitionStyle = UIModalPresentationCustom;
    source.modalPresentationStyle = UIModalPresentationCurrentContext;

    // When I am transitioning to a new one
    if(!self.reversed)
    {
        [source presentViewController:destination animated:YES completion:nil];
    }
    // Or reversing from a current one
    else
    {
        [source dismissViewControllerAnimated:YES completion:nil];
    }
}

如您所见,我已经设置了一个转换委托,该委托又调用了

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext

在我应用自定义动画的动画控制器上。但是现在当我在黄色视图上点击 Unwind to Red 时,它只会“展开”到其父级。 (例如蓝色的)。

当我将自定义转场排除在等式之外时,它工作得很好。它一直通向顶部。

现在我认为这与

有关
[source dismissViewControllerAnimated:YES];

line,因为这通常只是“上升”,所以我的问题是,我应该在那里调用什么,以便在需要时一直上升到红色?黄色是模态叠加。所以“pop too root”是行不通的。

【问题讨论】:

  • 您的transitionContext 在源、目标、框架和容器方面如何?我认为你不应该使用[source dismissViewControllerAnimated:YES];,你应该打电话给[transitionContext completeTransition:YES];

标签: ios objective-c animation transition segue


【解决方案1】:

指定自定义转场

解决方案是使用自定义转场来展开。 不幸的是,您不能像在普通 segue 上那样在界面构建器中为展开指定自定义 segue。您必须使用代码指定它。

UIViewController 上有一个可以覆盖的函数,称为 segueForUnwindingToViewController,它指定用于展开的 segue。棘手的部分是知道要在哪个视图控制器上覆盖此功能。答案是在您正在转换到/从的视图控制器的父级上执行此操作。就我而言,它是UINavigationController。导航控制器是第一个和第三个视图控制器的容器视图控制器。如果我在视图中嵌入了子视图控制器,那么答案将不是导航控制器而是父视图控制器。

通过从UINavigationController 继承来创建自定义导航控制器。然后确保在界面生成器中设置导航控制器的自定义类。现在您可以覆盖segueForUnwindingToViewController 函数。这是一个最小的实现。

class MyNavigationController: UINavigationController {
    override func segueForUnwindingToViewController(toViewController: UIViewController,
                                                    fromViewController: UIViewController,
                                                    identifier: String?) -> UIStoryboardSegue {
        return UIStoryboardSegue(identifier: identifier, source: fromViewController, destination: toViewController)
    }
}

为自定义 Segue 添加动画

override func segueForUnwindingToViewController(toViewController: UIViewController,
                                                    fromViewController: UIViewController,
                                                    identifier: String?) -> UIStoryboardSegue {
        return UIStoryboardSegue(identifier: identifier, source: fromViewController, destination: toViewController) {
            let fromView = fromViewController.view
            let toView = toViewController.view
            if let containerView = fromView.superview {
                let initialFrame = fromView.frame
                var offscreenRect = initialFrame
                offscreenRect.origin.x -= CGRectGetWidth(initialFrame)
                toView.frame = offscreenRect
                containerView.addSubview(toView)
                // Being explicit with the types NSTimeInterval and CGFloat are important
                // otherwise the swift compiler will complain
                let duration: NSTimeInterval = 1.0
                let delay: NSTimeInterval = 0.0
                let options = UIViewAnimationOptions.CurveEaseInOut
                let damping: CGFloat = 0.5
                let velocity: CGFloat = 4.0
                UIView.animateWithDuration(duration, delay: delay, usingSpringWithDamping: damping,
                        initialSpringVelocity: velocity, options: options, animations: {
                    toView.frame = initialFrame
                }, completion: { finished in
                    toView.removeFromSuperview()
                    if let navController = toViewController.navigationController {
                        navController.popToViewController(toViewController, animated: false)
                    }
                })
            }
        }
    }

详情from this post

【讨论】:

  • segueForUnwindingToViewController(to:from:identifier:) 在 iOS10 中已被弃用。
  • 你现在可以为展开指定自定义类
【解决方案2】:

您想使用 Navigation 控制器的 popToViewController:

 [source.navigationController popToViewController:destination animated:YES];

或者,使用animated:NO并将整个东西放在一个动画块中:例如:

UIViewAnimationOptions animation  = UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowAnimatedContent;

UIViewController *source = (UIViewController *) self.sourceViewController;
UIViewController *dest = (UIViewController *) self.destinationViewController;


[UIView transitionWithView:src.navigationController.view duration:0.4
                   options: animation
                animations:^{
                    [source.navigationController popToViewController:dest animated:NO];
                }
                completion:^(BOOL finished) {
                }];

【讨论】:

    【解决方案3】:
    1. 检查您的 UIStoryboardSegue 实施。您在帖子或实际代码中使用了modalTransitionStyle 是错字吗?更正:

      destination.modalPresentationStyle = UIModalPresentationCustom;
      
    2. 在没有编写自定义 UIStoryboardSegue 的情况下,我也取得了成功。尝试将“unwind to Red”按钮的操作方法链接到一个空的-unwindToRed: 方法而不覆盖-segueForUnwindingToViewController:(例如CTRL+从蓝色VC 中的按钮拖动到IB 中蓝色VC 的“Exit”字形并选择-unwindToRed:从列表中。)

    3. 如果 #2 没有关闭蓝色 VC,您可以尝试在 -unwindToRed: IBAction 方法中手动调用以下内容:

      [self dismissViewControllerAnimated:NO completion:nil];
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      相关资源
      最近更新 更多