我有两个视图控制器。在第一个我有一个按钮,它以模态显示第二个按钮。然后,我点击它上面的一个按钮关闭第二个(它下降)。为了解除转换,我创建了一个符合UIViewControllerAnimatedTransitioning
的自定义类,因此我为视图控制器使用自定义转换动画(我在解雇转换期间需要自定义行为)。
我的问题如下:由于我使用的自定义转换,我的视图控制器在转换完成后仍然会被删除,或者它是否仍然在屏幕外?如果是的话,它会影响记忆吗?有多糟糕?
答案 0 :(得分:4)
你说:
是我的视图控制器在转换完成后仍然被删除,或者它是否仍然在屏幕外?
这里有两个完全不同的问题。
首先,存在视图控制器层次结构的问题。当您呈现一个新的视图控制器时,旧的视图控制器始终保持在视图控制器层次结构中,以便当您关闭它时,它仍将存在。但是,当您解雇时,被解除的视图控制器将从视图控制器层次结构中删除(除非您执行某些不寻常的操作,例如在某处保留您自己的强引用),它将被释放。
其次,视图层次结构存在单独的问题。在呈现时,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 }
}
答案 1 :(得分:2)
ViewController
仍保留在层次结构中。
您可以通过验证模态视图控制器中self.parentViewController
属性的值来确认这一点。
修改:
该视图控制器会影响内存吗?
是的,它将继续在parentViewController中执行所有操作或活动(例如:流音频,播放动画,运行计时器等)。
如果是的话,如何处理这种情况?
UIViewController类中有一些方法可以检测ViewController何时出现/消失。
更具体地说,您可以使用以下方法:
您可以使用viewWillAppear
中的viewDidAppear
和parentViewController
来启动或恢复此类活动/操作。
并viewWillDisappear
和viewDidDisappear
暂停或停止此类活动/操作。
希望这有帮助。
答案 2 :(得分:1)
我假设您正在谈论您的模态view
停留在窗口层次结构中的viewController
- 因为您询问它是否仍在那里但是在屏幕外,我相信你在谈论视图和控制器,因为控制器永远不会出现在屏幕上。
如果您询问view
(我假设您是),在completeTransition
上调用transitionContext
会将其从窗口层次结构中删除(因此无需致电fromVC.view.removeFromSuperview()
) - 按照合同,当completeTransition
实施过渡完成后,您需要致电UIViewControllerAnimatedTransitioning
。
您可以在调用fromVC.view.superview
之前和之后检查transitionContext.completeTransition
的值来确认此行为:
UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
fromVC.view.frame = endFrame
}) { (_) in
print(">>> \(fromVC.view.superview)")
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
print(">>> \(fromVC.view.superview)")
}
答案 3 :(得分:0)
是的,之前的UIViewController仍在那里 如Apple docs
中所述viewControllerToPresent
视图控制器显示在 当前视图控制器的内容。