NSSearchField и NSSegmentedControl внутри NSToolbar
Настройка:
Я пишу основанное на документе приложение для OS X 10.11 с использованием раскадровок. Главное окно имеет NSToolbar
с 3-сегментным NSSegmentedControl
, При щелчке по сегментному элементу управления он должен переключать свернутое состояние NSSplitViewItem
в горизонтальном или вертикальном положении NSSplitView
, Поведение, которого я пытаюсь достичь, такое же, как и в Xcode 7, где сегментированный элемент управления на панели инструментов показывает / скрывает представления Navigator/Debug Area/Utilities.
В настоящее время сегментированный элемент управления отправляет действие первому респонденту. Метод действия реализуется NSSplitViewController
подкласс, который затем переключает это NSSplitViewItem
Разрушенное государство.
Эта проблема:
Проблема в том, что панель инструментов также содержит NSSearchField
, Если NSSearchField
имеет фокус, или даже если сам сегментированный элемент управления имеет фокус, нажав на NSSegmentedControl
с курсором не приводит к тому, что метод действия правильно пробирается по цепочке респондента к NSSplitViewController
подкласс.
Попытки решения:
Ранее я работал над этой проблемой, используя уведомления вместо цели / действия, но в итоге это оказалось слишком запутанным. Другая идея состоит в том, чтобы отправить сообщение контроллеру окна, который затем передаст его контроллеру представления контента, который передаст его контроллеру вертикального разделения, который затем отправит сообщение (при необходимости) в контроллер горизонтального разделения просмотра. Хотя я знаю, что это сработает, это также выглядело как уродливое решение, состоящее в том, чтобы добавить код к двум дополнительным файлам, которые просто передавали сообщение, но я подумал, что этого избежать цепочки респондентов.
Любые идеи будут очень благодарны.
Окончательное решение:
Я понял, что передача действия сегментированного элемента управления до первого респондента имеет смысл, только если важен контекст ключевого представления. В этом случае сегментированный элемент управления должен переключать свернутое состояние элементов разделенного представления в нескольких вложенных разделенных представлениях независимо от того, что является ключевым представлением.
Определите перечисление для представления областей разделенного представления:
enum SplitViewArea : Int {
// The raw values must match the order of the segmented control
case left, top, right
}
Определите протокол для сообщения о том, что разделенная область просмотра должна быть переключена:
protocol SplitViewTogglable {
func toggleSplitViewItem(matching area: SplitViewArea)
}
Реализуйте метод сегментированного управляющего действия в контроллере окна:
@IBAction func segmentedControlSelectionStateDidChange(_ sender: Any) {
guard let segmentedControl = sender as? NSSegmentedControl else { return }
guard let area = SplitViewArea(rawValue: segmentedControl.selectedSegment) else { return }
guard let togglable = contentViewController as? SplitViewTogglable else { return }
togglable.toggleSplitViewItem(matching: area)
}
Реализовать SplitViewTogglable
Метод протокола в подклассе NSSplitViewController:
func toggleSplitViewItem(matching area: SplitViewArea) {
switch area {
case .left:
leftSplitViewItem.isCollapsed = !leftSplitViewItem.isCollapsed
case .top:
// Nested NSSplitViewController that adopts SplitViewTogglable
if let togglable = centerSplitViewItem.viewController as? SplitViewTogglable {
togglable.toggleSplitViewItem(matching: area)
}
case .right:
rightSplitViewItem.isCollapsed = !rightSplitViewItem.isCollapsed
}
}
1 ответ
Это NSSplitViewController
установить как contentViewController
из окна? Как часть цепочки респондента для поиска цели действия, окно будет рассматривать его contentViewController
в качестве дополнительной цели, если она реагирует на селектор действий.
Когда поле поиска имеет ключевой фокус, цепочка респондента не проходит через область нормального содержимого, а вместо этого проходит через панель инструментов к окну. Таким образом, единственный способ, которым NSSplitViewController может быть частью этого поиска, - это contentViewController
,