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



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

为了让我的主ViewController不那么不受控制,我把所有这些按钮都放在了一个子视图中,该子视图从一个为菜单打开和关闭设置动画的笔尖加载。

然而,我想介绍这些视图控制器中的其他视图控制器,有时是"Modally",有时则是"Show"。我所做的似乎有效,但我只想知道这是否正常,或者我是否造成了一些我没有意识到的不必要的影响(比如会导致内存泄漏的强参考周期,或者其他什么)。或者有更好的方法吗?

某些代码:在菜单视图.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)
    }

In-ViewController.swift

        menuView.navigationController = self.navigationController as! CustomNavigationController

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


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

您应该始终在有问题的视图实际所属的控制器中处理视图和控制器之间的那种交互。如果需要将消息从视图发送到其视图控制器,可以使用委托方法或NSNotificationCenter类。

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

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中通信模式的更多信息,您可能想看看这篇很棒的文章,了解它们是如何工作的。

最新更新