从rootVC Subview访问UINavigationController(从Nib加载的子视图)

时间:2016-05-10 19:46:12

标签: swift uinavigationcontroller subview nib

主ViewController嵌入在UINavigationController子类中,VC有一个从nib加载的子视图。子视图称为MenuView,包含将链接到其他VC的UIButtons。

为了让我的主ViewController不那么难以驾驭,我已将所有这些按钮放入一个子视图中,该子视图从一个动画菜单打开和关闭动画的笔尖加载。

但是,我想提供其他视图控制器,有时候"模态"有时"显示"。我所做的似乎是有效的,但我只是想知道这是否正常,或者我是否引起了一些我不知道的不必要的影响(如导致内存泄漏的强引用循环,或者某些东西) )。或者有更好的方法吗?

一些代码: 在MenuView.swift中

class MenuView: UIView {
    var navigationController = CustomNavigationController()

    func combinedInit(){
        NSBundle.mainBundle().loadNibNamed("MenuViewXib", owner: self, options: nil)
        addSubview(mainView)
        mainView.frame = self.bounds
    }

    @IBAction func optionsAction(sender: AnyObject) {
        self.navigationController.performSegueWithIdentifier("presentOptions", sender: self)
    }

在ViewController.swift中

        menuView.navigationController = self.navigationController as! CustomNavigationController

1 个答案:

答案 0 :(得分:1)

简答:不,从层次结构中的某个视图中访问视图控制器是不行的,因为这会破坏所有写入的MVC规则。

UIView个对象用于在屏幕中显示UI组件,并负责正确绘制和布置其子视图。这就是全部。没什么,没什么。

您应该始终在所讨论的视图实际属于的控制器中处理视图和控制器之间的那种交互。如果需要将视图中的消息发送到其视图控制器,则可以使用delegate approachNSNotificationCenter类。

如果我在你的位置,当视图需要来自其视图控制器的一些信息时,我会使用委托。它比使用通知中心更容易理解,因为它可以更容易地跟踪它们之间发生的事情。如果视图控制器需要来自视图(换句话说,反过来)的一些信息,我会选择通知中心。

protocol MenuViewDelegate: class {
  func menuViewDidClick(menuView: MenuView)
}

class MenuView: UIView {
  var weak delegate: MenuViewDelegate?

  @IBAction func optionsAction(sender: AnyObject) {
    delegate?.menuViewDidClick(self)
  }
}

让我们看看视图控制器端发生了什么:

class MenuViewController: UIViewController, MenuViewDelegate {

  override func viewDidLoad() {
    ...
    self.menuView.delegate = self
  }

  func menuViewDidClick(menuView: MenuView) {
    navigationController?.performSegueWithIdentifier("presentOptions", sender: self)
  }
}

有关iOS中的通信模式的更多信息,您可能需要查看这篇出色的article,以便了解它们的工作原理。