我有两个视图控制器。在第一个上,我有一个按钮,它以模式显示第二个按钮。然后,我通过点击上面的按钮关闭第二个(它下降)。对于消除过渡,我创建了一个符合UIViewControllerAnimatedTransitioning
的自定义类,因此我对视图控制器使用自定义过渡动画(我需要在消除过渡期间的自定义行为)。
我的问题是:由于我使用的自定义过渡,我的视图控制器在过渡完成后是否仍然被删除,或者它仍然存在但不在屏幕上?如果是,会影响记忆力吗,有多糟糕?
你说:
过渡完成后,我的视图控制器是否仍被移除,或者它仍然存在但不在屏幕上?
这里有两个完全不同的问题。
首先,存在视图控制器层次结构的问题。当您呈现新的视图控制器时,旧的视图控制器始终保留在视图控制器层次结构中,以便当您关闭回它时,它仍然存在。但是,当您关闭时,已关闭的视图控制器将从视图控制器层次结构中删除(除非您执行异常操作,例如在某处保留自己对它的强引用)它将被解除分配。
其次,还有一个单独的视图层次结构问题。呈现时,UIPresentationController
指示表示视图控制器的视图是否保留在视图层次结构中。默认情况下,它将其保留在视图层次结构中,但通常,如果执行模式全屏"呈现",您将指定一个UIPresentationController
子类,告诉它在过渡完成后删除呈现视图控制器的视图。
例如,当执行自定义模式"呈现"过渡时,其中呈现的视图控制器的视图是不透明的并覆盖整个屏幕,则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 }
}
ViewController
保留在层次结构中。
您可以通过在模态视图控制器中验证self.parentViewController
属性的值来确认这一点。
编辑:
该视图控制器会影响内存吗?
是的,它将继续在父视图控制器中执行所有操作或活动(例如:流式传输音频,播放动画,运行计时器等)。
如果是这样,如何处理这种情况?
UIViewController 类中有一些方法可用于检测视图控制器何时出现/消失。
更具体地说,您可以使用以下方法:
- viewWillAppear(通知视图控制器其视图即将添加到视图层次结构中)
- viewDidAppear(通知视图控制器其视图已添加到视图层次结构中)
- viewWillDisappear(通知视图控制器其视图即将从视图层次结构中删除)
- viewDidDisappear(通知视图控制器其视图已从视图层次结构中删除)
您可以使用viewWillAppear
和viewDidAppear
parentViewController
来启动或恢复此类活动/操作。
并viewWillDisappear
和viewDidDisappear
暂停或停止此类活动/操作。
希望这有帮助。
我将假设您正在谈论停留在窗口层次结构中的模态viewController
view
- 因为您问它是否仍然存在但不在屏幕上,我相信您正在谈论视图和控制器,因为控制器永远不会在屏幕上。
如果你问的是view
(我假设你是),在transitionContext
上调用completeTransition
会将其从窗口层次结构中删除(所以没有必要调用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)")
}
是的,以前的UIViewController仍然存在。
如苹果文档中所述
viewControllerToPresent
要在 当前视图控制器的内容。