使用自定义转换时,视图控制器是否会被完全删除?
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 何时出现/消失。
更具体地说,您可以使用以下方法:
- viewWillAppear(通知视图控制器其视图即将添加到视图层次结构中)
- viewDidAppear(通知视图控制器其视图已添加到视图层次结构中)
- viewWillDisappear(通知视图控制器其视图即将从视图层次结构中删除)
- viewDidDisappear(通知视图控制器其视图已从视图层次结构中删除)
您可以在 parentViewController
中使用 viewWillAppear
和 viewDidAppear
来开始或恢复此类活动/操作。
并且 viewWillDisappear
和 viewDidDisappear
暂停或停止此类活动/操作。
希望对您有所帮助。
是的,之前的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 }
}
我假设你说的是你的模态 viewController
的 view
留在 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)")
}
我有两个视图控制器。在第一个上我有一个按钮,它以模态方式显示第二个。然后,我通过点击一个按钮关闭第二个(它下降)。为了关闭过渡,我创建了一个符合 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 何时出现/消失。
更具体地说,您可以使用以下方法:
- viewWillAppear(通知视图控制器其视图即将添加到视图层次结构中)
- viewDidAppear(通知视图控制器其视图已添加到视图层次结构中)
- viewWillDisappear(通知视图控制器其视图即将从视图层次结构中删除)
- viewDidDisappear(通知视图控制器其视图已从视图层次结构中删除)
您可以在 parentViewController
中使用 viewWillAppear
和 viewDidAppear
来开始或恢复此类活动/操作。
并且 viewWillDisappear
和 viewDidDisappear
暂停或停止此类活动/操作。
希望对您有所帮助。
是的,之前的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 }
}
我假设你说的是你的模态 viewController
的 view
留在 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)")
}