正确释放嵌入在子视图中的NSViewController

时间:2016-08-11 10:30:38

标签: swift cocoa nsviewcontroller subviews

我有一个任务是编写一个小应用程序,其中各种控制器必须嵌入在默认控制器中。所有控制器都存储在一个故事板中。

在子视图中嵌入控制器的示例代码


    if let id = getControllerId(pageIndex) { // get controller's storyboard id by segmented index
      let storyBoard = NSStoryboard(name: "Main", bundle: nil)
      let controller = storyBoard.instantiateControllerWithIdentifier(id) as! NSViewController
      controller.view.translatesAutoresizingMaskIntoConstraints = false
      if self.view.subviews.count > 0 {
        let prevView = self.view.subviews[0]
        prevView.removeFromSuperview() // here should be releasing previous controller
      }
      self.view.addSubview(controller.view)
      // make all side constraints
      let views = ["view": controller.view]
      self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-(0)-[view]-(0)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
      self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(0)-[view]-(0)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
    } else {
      NSLog("ERROR: Unable get controller storyboard id for index \(pageIndex)")
    }

我注意到嵌入式控制器不执行viewWillDisappear。我需要这个事件来清除观察者和其他一些东西。

我不确定将控制器显示为嵌入在子视图中的正确方法,但我没有找到任何其他解决方案。

我制作示例项目来测试这种情况

https://github.com/avvensis/embeddedviewcontrollers

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

viewWillDisappear不执行,因为你不隐藏任何东西。

你创建他后,你的控制器会很快死掉。因此,第一步是对其进行引用:

  class ViewController: NSViewController {

// MARK: - Custom properties

let pageIds: [String] = ["redController", "yellowController", "greenController"]

var currentControler : NSViewController!

...

private func showEmbeddedController(pageIndex: Int) {
if let id = getControllerId(pageIndex) { // get controller's storyboard id by segmented index
  let storyBoard = NSStoryboard(name: "Main", bundle: nil)
  currentControler = storyBoard.instantiateControllerWithIdentifier(id) as! NSViewController
  currentControler.view.translatesAutoresizingMaskIntoConstraints = false
  if self.view.subviews.count > 0 {
    let prevView = self.view.subviews[0]
    prevView.removeFromSuperview() // here should be releasing previous controller
  }
  self.view.addSubview(currentControler.view)
  // make all side constraints
  let views = ["view": currentControler.view]
  self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-(0)-[view]-(0)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
  self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(0)-[view]-(0)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
} else {
  NSLog("ERROR: Unable get controller storyboard id for index \(pageIndex)")
}
}


}

然后在你的基本控制器中使用deinit方法:

 class EmbeddedViewController: NSViewController {

...

deinit {
    print("DEBUG: \(self.className) deinit")
}

}