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,

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