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

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

введите здесь описание изображения

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

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

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

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

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

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

person gbdavid    schedule 10.07.2015    source источник


Ответы (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.

person lukkea    schedule 03.07.2016
comment
@gbdavid здорово! рад помочь; мне понадобился только год, чтобы сделать это! - person lukkea; 04.07.2016