ios - 自定义展开转场动画

标签 ios objective-c animation transition segue

我有以下设置:

Setup idea

红色 Controller 有一个方法

- (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];
    }
}

如你所见,我已经设置了一个转换委托(delegate),它会依次调用

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

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

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

现在我认为这与

[source dismissViewControllerAnimated:YES];

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

最佳答案

指定自定义 Segue

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

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

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

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

为自定义转场添加动画

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

关于ios - 自定义展开转场动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24530662/

相关文章:

iphone - NSTimer - 二进制 % 错误的无效操作数

objective-c - N窗口消失

ios - 如何在 iOS 上创建动画入职

ios - 更改 NSLayoutConstraint 时的 SWIFT 动画

ios - 预期标识符

ios - 使用 UITapGestureRecognizer 显示 UIPickerView

ios - itemSize 没有使用 setCollectionViewLayout(toLayout, animated : true);

ios 阻止潜在的内存泄漏

iPhone 针对某些设备

swift - Swift 中使用 View 的 LED 横幅