自定义展开segue动画

时间:2014-07-02 12:03:44

标签: ios objective-c animation transition segue

我有以下设置:

Setup idea

红色控制器有一个方法

- (IBAction)unwindToRed:(UISegue *)segue

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

返回此事件的自定义segue。

在我的自定义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时,它只会&#34;展开&#34;给它的父母。 (例如蓝色的)。

当我将自定义segue从等式中移开时,它可以正常工作。它一路走到顶端。

现在我认为这与

有关
[source dismissViewControllerAnimated:YES];

行,因为那通常只是&#34;一个&#34;我的问题是,我想,我应该在那里打电话,以便在需要时一直到红色?黄色是模态叠加。所以&#34;流行太多根&#34;不行。

3 个答案:

答案 0 :(得分:1)

指定自定义搜索

解决方案是使用自定义segue进行展开。 很遗憾,您无法像在正常的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

答案 1 :(得分:0)

您想使用导航控制器的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) {
                }];

答案 2 :(得分:-1)

  1. 检查您的UIStoryboardSegue实施情况。您在帖子或实际代码中使用modalTransitionStyle拼写错误了吗?校正:

    destination.modalPresentationStyle = UIModalPresentationCustom;
    
  2. 我在没有编写自定义UIStoryboardSegue的情况下也取得了成功。尝试将&#34;展开到红色&#34;按钮的操作方法为空-unwindToRed:方法而不覆盖-segueForUnwindingToViewController:(例如,从蓝色VC中的按钮CTRL +拖动到蓝色VC&#34;&#34;退出&#34 ; IB中的字形并从列表中选择-unwindToRed:。)

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

    [self dismissViewControllerAnimated:NO completion:nil];