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

时间:2018-02-03 17:53:50

标签: ios cocoa-touch uiviewcontroller

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

我的问题如下:由于我使用的自定义转换,我的视图控制器在转换完成后仍然会被删除,或者它是否仍然在屏幕外?如果是的话,它会影响记忆吗?有多糟糕?

4 个答案:

答案 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何时出现/消失。
更具体地说,您可以使用以下方法:

  1. viewWillAppear(通知视图控制器其视图即将添加到视图层次结构中)
  2. viewDidAppear(通知视图控制器其视图已添加到视图层次结构中)
  3. viewWillDisappear(通知视图控制器其视图即将从视图层次结构中删除)
  4. viewDidDisappear(通知视图控制器其视图已从视图层次结构中删除)
  5. 您可以使用viewWillAppear中的viewDidAppearparentViewController来启动或恢复此类活动/操作。
    viewWillDisappearviewDidDisappear暂停或停止此类活动/操作。

    希望这有帮助。

答案 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
  视图控制器显示在   当前视图控制器的内容。