UIViewController自定义过渡卡在iOS13上

时间:2019-09-05 09:46:58

标签: ios swift uiviewcontroller ios13

我已经在iOS应用中实现了两个视图控制器之间的自定义过渡,并且可以在iOS 10、11和12上正常工作。

现在,我想使用Xcode 11 beta 6和iOS 13 beta 8为iOS 13做好准备,但是过渡很困难。

自定义过渡应将第一个视图控制器向上移动并移出屏幕,第二个视图控制器从下向上移出。但是现在它又回到了iOS13的默认表示样式pageSheet,只是将第一个视图控制器缩小了一点,并添加了暗淡的叠加层。但是第二个视图没有出现。

我发现在方法animatePresentation(context: UIViewControllerContextTransitioning)context不会返回'from'视图,因此context.view(forKey: .from)返回nil

如果没有'from'视图,我该怎么办?

FlyUpTransition.swift

class FlyUpTransition: NSObject, UIViewControllerAnimatedTransitioning {

    var mode: Mode = .present

    enum Mode {
        case present
        case dismiss
    }

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return TimeInterval(0.45)
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        switch mode {
        case .present:
            animatePresentation(context: transitionContext)
        case .dismiss:
            animateDismissal(context: transitionContext)
        }
    }

    func animatePresentation(context: UIViewControllerContextTransitioning) {
        guard let fromView = context.view(forKey: .from), let toView = context.view(forKey: .to) else { return }
        ...
    }

    func animateDismissal(context: UIViewControllerContextTransitioning) {
        guard let fromView = context.view(forKey: .from), let toView = context.view(forKey: .to) else { return }
        ...
    }
}

4 个答案:

答案 0 :(得分:14)

TL; DR

这是iOS中的错误,但是您可以使用context.viewController(forKey:.from).view作为解决方法。

详细信息

这似乎是iOS 13.0中的错误。自iOS 13.1 beta 3起,它仍然存在。 http://www.openradar.me/radar?id=4999313432248320

在某些情况下,转换上下文的view(forKey:)方法错误地返回nil。当呈现视图控制器以非模态呈现时,view(forKey: .from)似乎正在发生这种情况。从非模态视图控制器中消除最初显示的视图控制器时,view(forKey: .to)的结果也为nil。

我不仅在iPhone上的新工作表样式演示中观察到了这种情况,而且还在iPad上的普通表单和弹出窗口中观察到了这一点。

此问题的另一个体现似乎是,当被问及该视图控制器的最终框架应该是什么时,finalFrame(for:)方法返回了错误的CGRect。在我的测试中,即使正确的视图较小,它也会返回全屏矩形。

一种解决方法是使用viewController(forKey:)方法返回的视图控制器的根视图控制器,尽管the documentation明确阻止:“此方法返回的视图可能是或可能不是该视图的根视图。相应的视图控制器。”

答案 1 :(得分:7)

好的,即使这是Apple的API重大更改,也很容易。

viewController.modalPresentationStyle = .fullScreen

现在,我必须浏览我的整个项目,并检查所有模态演示是否仍按我的需要。

答案 2 :(得分:1)

上面的答案将modalPresentationStyle设置为.fullScreen是正确的,但是也值得一提的是,如果您的视图控制器嵌入在UINavigationController中,则需要将其设置为导航控制器:

navigationController.modalPresentationStyle = .fullScreen

答案 3 :(得分:0)

我通过从集合VC拖放到另一个VC来设置IB中的序列,该VC用于显示详细信息。

我在这个问题上有了新发现,要引用'toView'和'fromView',以下两种方法都可以使用

间接方式:

transitionContext.viewController(forKey: .to)?.view
transitionContext.viewController(forKey: .from)?.view

直接方式:

transitionContext.view(forKey: .to)
transitionContext.view(forKey: .from)

但是,当我将segue样式切换为“ Over Full Screen”时,直接方式对于“ toView”和“ fromView”都返回“ nil”,并且只能间接地起作用。

希望这对将来的人会有所帮助。

P.S。这是我到solve another problem途中的发现,如果您还遇到“正在运行的动画师”在iOS 13及更高版本中停止工作的问题,这可能会有所帮助