在自定义模式解除转换后,第一个视图控制器的生命周期方法不会被调用

Posted

技术标签:

【中文标题】在自定义模式解除转换后,第一个视图控制器的生命周期方法不会被调用【英文标题】:After custom modal dismissal transition the first view controller's lifecycle methods don't get called 【发布时间】:2018-06-13 18:43:59 【问题描述】:

我有两个视图控制器:viewController1viewController2viewController1 包含一个包含多个单元格的集合视图。

它们通过模态序列连接。为了在它们之间导航,我创建了两个动画师来显示 viewController2 (showAnimator) 和关闭它 (dismissAnimator)。

dismissAnimator 中,我为fromViewviewController2 的视图)和toViewviewController1 的视图)设置了动画。以下是执行此操作的两种方法:

 private func animateFromViewDisappearance(fromView: UIView?, withDuration duration: TimeInterval, usingTransitionContext transitionContext: UIViewControllerContextTransitioning?) 
    guard let containerView = transitionContext?.containerView, let fromView = fromView else return

    UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: 
        fromView.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
        fromView.alpha = 0.0
    , completion: _ in

    )


 private func animateToViewAppearance(toView: UIView?, withDuration duration: TimeInterval, usingTransistionContext transitionContext: UIViewControllerContextTransitioning?) 
    guard let containerView = transitionContext?.containerView, let toView = toView else 
        return


    toView.frame = containerView.frame
    toView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
    toView.alpha = 0.0
    containerView.addSubview(toView)

    UIView.animate(withDuration: duration, delay: 0.3, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: 
        toView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
        toView.alpha = 1.0
    )  (success) in
        if success 
            transitionContext?.completeTransition(true)
        
    

这些方法是从animateTransition(using:) 调用的。

问题是动画结束后,集合视图的viewController1 单元格没有出现。我只是得到视图控制器的视图和集合视图本身。我检查并注意到视图控制器的生命周期方法也没有被调用,但是,viewDidLayoutSubviews 确实被调用了。集合视图数据源方法也不会被调用,这就是单元格不出现的原因。

我知道我错过了一些非常简单的东西,但不知道是什么。我也在这里检查了一些答案,但没有一个对我有帮助。

如果您知道如何解决此问题,我将不胜感激。

【问题讨论】:

为什么不在第一个函数中调用complete @Alper,我需要在转换完成后调用它,但是,该方法仅将 viewController2 动画关闭屏幕,但转换仍在发生(我需要动画 viewController1 )。如果我在那里调用它,应用程序会崩溃,因为它希望在调用之后,所有过渡动画都已完成。 这些是同时调用的? @Alper,在animateTransition(using:)方法中一个接一个。 你确定complete被调用了吗? 【参考方案1】:

花了一些时间后,我终于找到了解决方案。正如 Apple 文档中所说,我们不能直接调用视图控制器的生命周期方法(可以,但不推荐)。要调用 viewController1 生命周期方法,我从 animator 调用 beginAppearanceTransition(_:animated:) 方法:

 toViewController?.beginAppearanceTransition(true, animated: true)

现在,这确实调用了视图控制器的生命周期方法,但是视图布局变得一团糟(我认为,那是因为最初从 viewController1 转换时,我不仅改变了它的位置,还改变了它的规模)。

所以,最后我也找到了解决这个问题的方法。为了解决这个问题,当从viewController1 转换时,我不是为视图控制器本身(它的位置和比例)设置动画,而是使用它的快照(以下代码在动画器中用于从viewController1 转换到viewController2):

 let snapshot = UIApplication.shared.keyWindow?.snapshotView(afterScreenUpdates: false)

获得快照后,一旦开始转换,我将快照插入viewController1 顶部的containerView,并从超级视图中删除viewController1。现在,我为快照制作动画,它模仿了viewController1

这对我来说很好。也许它会对其他人有用。

【讨论】:

以上是关于在自定义模式解除转换后,第一个视图控制器的生命周期方法不会被调用的主要内容,如果未能解决你的问题,请参考以下文章

在自定义视图控制器转换中抑制导航推送动画

使用自定义转换时视图控制器是不是会被完全删除?

如何在解除第二个控制器后调用第一个控制器中的函数

iOS - 使用 NSNotificationCenter 的生命周期

当模态视图控制器被解除时如何调用函数

模式解除后返回导航控制器索引(无情节提要)