【问题标题】:Proper way to remove UIViewController删除 UIViewController 的正确方法
【发布时间】:2017-07-24 01:31:02
【问题描述】:

我有一个settingsController,它是一个自定义的UINavigationController,它必须出现和消失。

它的 XIB 位于故事板中,由于其他管理目的,我必须使用 var settingsController 跟踪它。

主视图控制器:

class MainViewController: UIViewController {

    var settingsController : MySettingsNavigationController?

    func settingsButtonPressed () {
        let storyboard = UIStoryboard(name: "Main Storyboard", bundle: nil)
        self.settingsController = storyboard.instantiateViewController(withIdentifier: "Settings Navigation Controller") as? MySettingsNavigationController
        self.settingsController!.transitioningDelegate = self
        self.settingsController!.modalPresentationStyle = .custom
        self.present(self.settingsController!, animated: true, completion: nil)
    }

    //Settings View Controller Transition Methods
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerView = transitionContext.containerView
        let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
        let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
        if(self.isSettingsPresenting == true) {
            toViewController!.view.alpha = 1;
            toViewController!.view.transform = CGAffineTransform(scaleX: 0.001, y: 0.001);
            toViewController!.view.center = self.settingsButton.center

            UIView.animate(withDuration: 0.5, delay: 0,
                           options: [.curveEaseIn], animations: { () -> Void in

                toViewController!.view.alpha = 1;
                toViewController!.view.transform = CGAffineTransform(scaleX: 1, y: 1);
                toViewController!.view.center = fromViewController!.view.center
                containerView.addSubview(toViewController!.view)

            }, completion: { (completed) -> Void in

                transitionContext.completeTransition(completed)

            })

        } else {
            UIView.animate(withDuration: 0.5, delay: 0,
                           options: [.curveEaseOut], animations: { () -> Void in

                fromViewController!.view.alpha = 0;
                fromViewController!.view.transform = CGAffineTransform(scaleX: 0.01, y: 0.01);
                fromViewController!.view.center = self.settingsButton.center

            }, completion: { (completed) -> Void in
                //Two lines below added later to test..
                fromViewController?.view.removeFromSuperview()
                fromViewController?.removeFromParentViewController()
                transitionContext.completeTransition(completed)
            })
        }
    }
}

设置导航控制器:

class MySettingsNavigationController:  UINavigationController, UINavigationControllerDelegate
{
    .....

    func closeButtonPressed (_ sender: UIButton!) {
        self.dismiss(animated: true, completion: {
            //Tried removing self in here...
        })
    }
}

问题:

当我打开settingsController 并关闭它时,settingsController 分配的内存永远不会被释放;不知何故,settingsController 没有被释放。

注意:

我不得不这样做:

  1. 从情节提要启动视图控制器
  2. 使用自定义动画过渡
  3. 不使用自定义委托(因为我无法将委托写入 已经是UINavigationControllerDelegate。这本来可以给 我有机会回电给家长,MainViewController 准备好被移除

【问题讨论】:

  • settingsController设置为weak是否有效?
  • 我试着让它变弱。不知何故,它仍然没有被正确删除。如果我注销settingsController,动画完成后,还是显示它是活着的..
  • 你能否使用协议让MainViewController 知道SettingsViewController 想要解雇,并从那里解雇Settings,并在完成时将settingsController 设置为nil?
  • 我知道如何做到这一点的唯一方法是创建一个 SettingsViewController 委托。但是 Swift 对我大喊大叫,说已经有一个 UINavigationControllerDelegate。
  • SettingsViewController 是否可以使用协议?

标签: ios swift xcode uiviewcontroller uistoryboard


【解决方案1】:

不知何故,settingsController 没有被释放

  • var settingsController 看起来可能是罪魁祸首。
    ViewController 作为var 对象持有是非常不鼓励

由于其他管理目的,我必须使用 'var settingsController' 对其进行跟踪。

  • 使用提供controller 相关属性数据或处理用户交互的sharedHelper-esque 类进行评估。
  • 除了settingsButtonPressed(应该单独负责调用settingsController)之外,没有任何功能应该被设计成需要settingsController 的实例才能执行。此类功能所需的数据可以通过protocolsblocksshared instances等多种方式提取。

【讨论】:

  • 例如,如果您有一个来来去去的设置屏幕,如果没有 var,您将如何查看它是否在不同的场合出现?
  • 您可以在设置屏幕的演示和关闭时触​​发NSNotification。感兴趣的对象(可能是ViewController)可以成为此通知的观察者并在之后执行相关操作。
  • 我想摆脱上面的简单方法是将委托写入 settingsController。然而,由于它是一个 UINavigationController,所以 swift 大喊它已经有一个委托:UINavigationControllerDelegate。有没有办法仍然这样做?
  • 如果不了解实现细节,我不确定这是否是一种简单的方法。您可以考虑扩展UINavigationControllerDelegate 协议以提供所需的附加功能。签出:stackoverflow.com/questions/732701/…
猜你喜欢
  • 2012-07-19
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多