Swift/Cocoa: как привязать значение к выбранной в данный момент вкладке
Работа на панели настроек. У меня есть NSTabView; вкладки создаются динамически из XIB. Они все очень похожи, но не идентичны. Итак, мне нужно изменить некоторые значения (и некоторые элементы управления, чтобы они появлялись или исчезали) в зависимости от того, какая вкладка выбрана в данный момент.
Обычно можно подумать, что можно связать с NSTabView.selectedTabViewItem; но это не работает. Зачем? Значение никогда не обновляется.
Затем я стал более креативным и подумал о создании вычисляемого свойства, которое возвращает соответствующее значение для наблюдаемой привязки. Все еще нет игры в кости. Привязки оцениваются при запуске приложения и никогда не обновляются.
Затем я решил запутаться и сделал делегата для реализации метода didSelect tabView, посредством которого выбранная в данный момент вкладка записывается в сохраненное свойство, которое может наблюдать привязка.
Этот последний подход работает, но он кажется очень неуклюжим и грязным. Кто-нибудь знает лучший способ?
Редактировать: я пытаюсь реализовать NSTabViewController, но я просто не могу заставить его работать!
Если я вручную привяжу NSTabViewController к объекту NSTabView, который я сделал в IB, все будет правильно инициализировано, но вкладки никогда не будут отображаться. И, если я пытаюсь инициализировать все в контроллере, а затем назначить NSTabView через свойство NSTabViewController.tabView, я получаю
A TabView managed by a TabViewController cannot have its delegate modified
Что странно, потому что я пытаюсь сделать это так, как указывает do cumentation. На самом деле, даже если я пытаюсь сделать TabViewController.tabView = NSTabView()
Я получаю ту же ошибку. Это ошибка?
Вот вся соответствующая часть моего кода,
@IBOutlet weak var theTabView: NSTabView?
@IBOutlet weak var tabViewDelegate: NSTabViewController?
override func assignMainView() {
ControllersRef.sharedInstance.tabViewController = self.tabViewController
ControllersRef.sharedInstance.theTabView = self.theTabView
ControllersRef.sharedInstance.thePrefPane = self
let tabs = ["Internet", "URL Schemes", "Uniform Type Identifiers", "Applications"]
if let tabViewDelegate = self.tabViewDelegate {
for tab in tabs {
let newTab = NSTabViewItem(viewController: NSViewController.init()) // I tried doing it the other way around also, i.e. via addChildViewController() and tabItem(for:), but the result was the same.
newTab.label = tab
let newTabViewItemView = DRYView.init()
newTabViewItemView.nibName = "SWDAPrefpaneTabTemplate"
tabViewDelegate.addChildViewController(newTab.viewController!)
newTab.viewController!.view = newTabViewItemView
}
let views = tabViewDelegate.childViewControllers
tabViewDelegate.tabView = ControllersRef.sharedInstance.theTabView
}
super.assignMainView()
}
1 ответ
Вы должны быть в состоянии использовать NSTabViewController
И его selectedTabViewItemIndex
свойство, которое специально задокументировано как совместимое с привязками.
Если вам нужно, вы можете создать вычисляемое свойство, построенное поверх selectedTabViewItemIndex
сопоставить с соответствующим объектом модели для выбранного элемента. Когда вы это сделаете, обязательно реализуйте метод класса keyPathsForValuesAffecting<Key>
возвращать ["selectedTabViewItemIndex"]
так что KVO знает, что нужно считать вашу вычисленную собственность как измененную selectedTabViewItemIndex
изменения.
(Возможно, этого недостаточно для того, чтобы вычисленное свойство, которое вы уже пробовали, работает, потому что NSTabView
"s selectedTabViewItem
сам по себе не задокументирован как соответствующий KVO.)