Как получить доступ к splitViewItems по имени элемента в Swift + Раскадровки

В настоящее время я использую NSSplitViewController, который имеет два дочерних элемента разделенного представления (один представляет собой View Controller, а другой - другой Split View Controller, как показано ниже:

Я хотел бы получить доступ к элементам разделенного вида программно, чтобы изменить состояние свертывания (а затем и некоторые другие свойства) из контроллера окна.

Я могу легко получить доступ к элементам разделенного вида по позиции, используя это:

    let myMainSplitViewController = self.contentViewController as! NSSplitViewController
    let mySplitViewController2 = myMainSplitViewController.splitViewItems[1]
    mySplitViewController2.collapsed = !mySplitViewController2.collapsed

Я думаю, что в долгосрочной перспективе использование позиции (1 в примере) не будет хорошей идеей (например, если я переставлю разделенные элементы в будущем). Есть ли способ получить доступ к элементам разделенного представления с более постоянной ссылкой, например, по номеру индекса?

Я думаю, что мог бы попытаться присвоить Storyboard ID контроллерам элементов разделенного представления и найти точный по имени, используя метод фильтра массива, но это может быть немного громоздко... Есть ли что-то проще, как это?:

myMainSplitViewController.splitViewItems["My Split View Controller 2"] 

1 ответ

Решение

Если у ваших элементов разделенного вида есть пользовательские контроллеры, вы можете получить к ним доступ через NSSplitViewController.splitViewItemForViewController(viewController: NSViewController),

Я бы объявил протокол для каждого контроллера представления:

protocol MainSplitViewControllerProtocol {
  var thisSplitItemController: ThisSplitViewItemControllerProtocol? {get set}
  var thatSplitItemController: ThatSplitViewItemControllerProtocol? {get set}
}

protocol ThisSplitViewItemControllerProtocol {
  //any contracts you need here
}

protocol ThatSplitViewItemControllerProtocol {
  //any contracts you need here
}

Тогда я бы объявил мои конкретные классы так:

class MainSplitViewController: NSSplitViewController, MainSplitViewControllerProtocol {
  var thisSplitItemController: ThisSplitViewItemControllerProtocol?
  var thatSplitItemController: ThatSplitViewItemControllerProtocol?
  var thisSplitViewItem: NSSplitViewItem?
  var thatSplitViewItem: NSSplitViewItem?

  override func viewWillAppear() {
    thisSplitViewItem = thisSplitItemController != nil ? self.splitViewItemForViewController(thisSplitItemController as! NSViewController : nil)
    thatSplitViewItem = thatSplitItemController != nil ? self.splitViewItemForViewController(thatSplitItemController as! NSViewController : nil)
  }
}

class ThisViewController: NSViewController, ThisSplitViewItemControllerProtocol {
  var parent: MainSplitViewControllerProtocol?

  override func viewdidLoad() {
    super.viewDidLoad()
    parent = (self.parentViewController as! MainSplitViewControllerProtocol)
    parent?.thisSplitItemController = self
  }
}

class ThatViewController: NSViewController, ThatSplitViewItemControllerProtocol {
  var parent: MainSplitViewControllerProtocol?

  override func viewdidLoad() {
    super.viewDidLoad()
    parent = (self.parentViewController as! MainSplitViewControllerProtocol)
    parent?.thatSplitItemController = self
  }
}

Теперь я могу получить доступ к элементам разделенного представления независимо от их индекса в родительском массиве splitViewItems:

extension MainSplitViewController {
  func toolbarButtonClick(button: NSButton) {
    thisSplitViewItem?.collapsed = !thisSplitViewItem?.collapsed
    thatSplitViewItem?.collapsed = !thatSplitViewItem?.collapsed
  }
}

Используя протоколы, я также отделил все контроллеры представлений, чтобы их можно было легко заменить. Если вам нужно управлять свернутым состоянием одного из NSSplitViewItems (или любых других свойств) из другого NSSplitViewItem, добавьте соответствующий NSSplitViewItem в качестве свойства к вашему протоколу NSSplitViewController.

Другие вопросы по тегам