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

Does a view controller get removed entirely when using a custom transition?

我有两个视图控制器。在第一个上我有一个按钮,它以模态方式显示第二个。然后,我通过点击一个按钮关闭第二个(它下降)。为了关闭过渡,我创建了一个符合 UIViewControllerAnimatedTransitioning 的自定义 class,因此我为视图控制器使用自定义过渡动画(在关闭过渡期间我需要一个自定义行为)。

我的问题如下:由于我使用了自定义转场,我的视图控制器在转场结束后是否仍会被删除,或者它是否仍然存在但不在屏幕上?如果是,会不会影响内存,有多糟糕?

ViewController 保留在层次结构中。

您可以通过在模态视图控制器中验证 self.parentViewController 属性 的值来确认这一点。

编辑:

Will that view controller affect the memory?

是的,它将继续在父级ViewController.

中执行所有操作或活动(例如:流音频、播放动画、运行 计时器等)

And if so, how can this situation be handled?

UIViewController class 中有一些方法可以检测 ViewController 何时出现/消失。
更具体地说,您可以使用以下方法:

  1. viewWillAppear(通知视图控制器其视图即将添加到视图层次结构中)
  2. viewDidAppear(通知视图控制器其视图已添加到视图层次结构中)
  3. viewWillDisappear(通知视图控制器其视图即将从视图层次结构中删除)
  4. viewDidDisappear(通知视图控制器其视图已从视图层次结构中删除)

您可以在 parentViewController 中使用 viewWillAppearviewDidAppear 来开始或恢复此类活动/操作。
并且 viewWillDisappearviewDidDisappear 暂停或停止此类活动/操作。

希望对您有所帮助。

是的,之前的UIViewController还在。
Apple docs

中所述

viewControllerToPresent
The view controller to display over the current view controller’s content.

你说:

is my view controller still get removed after the transition finishes or is it still there but off the screen?

这里有两个完全不同的问题。

首先,有一个视图控制器层次结构的问题。当你呈现一个新的视图控制器时,旧的视图控制器总是保存在视图控制器层次结构中,这样当你返回它时,它仍然会在那里。然而,当你解雇时,被解雇的视图控制器将从视图控制器层次结构中删除,并且(除非你做了一些不寻常的事情,比如在某处保留你自己对它的强引用)它将被释放。

其次,还有一个视图层次的单独问题。呈现时,UIPresentationController 指示呈现视图控制器的视图是否保留在视图层次结构中。默认情况下,它将它保留在视图层次结构中,但通常如果执行模态全屏 "present",您将指定一个 UIPresentationController 子类,告诉它在转换完成。


例如,当执行自定义模式 "present" 转换时,呈现的视图控制器的视图是不透明的并覆盖整个屏幕,那么您的 UIViewControllerTransitioningDelegate 不仅会提供动画控制器,还会指定演示控制器:

func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return YourAnimationController(...)
}

func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return YourAnimationController(...)
}

func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
    return PresentationController(presentedViewController: presented, presenting: presenting)
}

而且该演示控制器可能非常小,只告诉它删除演示者的视图:

class PresentationController: UIPresentationController {
    override var shouldRemovePresentersView: Bool { return true }
}

我假设你说的是你的模态 viewControllerview 留在 window 层次结构中 - 因为你问的是它是否仍然存在但已关闭屏幕,我相信你在谈论视图和控制器,因为控制器永远不会出现在屏幕上。

如果您询问 view(我假设您是),在 transitionContext 上调用 completeTransition 会将其从 window 层次结构中删除(因此无需调用 fromVC.view.removeFromSuperview()) - 根据合同,当在 UIViewControllerAnimatedTransitioning 实现中完成转换时,您需要调用 completeTransition

您可以通过在调用 transitionContext.completeTransition 之前和之后检查 fromVC.view.superview 的值来确认此行为:

UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
    fromVC.view.frame = endFrame
}) { (_) in
    print(">>> \(fromVC.view.superview)")
    transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    print(">>> \(fromVC.view.superview)")
}