6

Finder と Notes には、私が再現しようとしている独特の動作があります。NSToolbar の「柔軟なスペース」は、分割ビューのサイズを考慮しているようです。たとえば、ボタンの最初のグループは、サイドバーの左側と右側に配置されます。アイコンの 2 番目のグループは、最初の列の右側に配置されます。サイドバーを広げると、ツールバーの項目も一緒に移動します。

これを再現することは可能ですか?

ここに画像の説明を入力


解決

@KenThomases が提供するソリューションを使用して、次のように実装しました。

final class MainWindowController: NSWindowController {
    override func windowDidLoad() {
        super.windowDidLoad()
        window?.toolbar?.delegate = self
        // Make sure that tracking is enabled when the toolbar is completed
        DispatchQueue.main.async {
            self.trackSplitViewForFirstFlexibleToolbarItem()
        }
    }
}

extension MainWindowController: NSToolbarDelegate {
    func toolbarWillAddItem(_ notification: Notification) {
        // Make sure that tracking is evaluated only after the item was added
        DispatchQueue.main.async {
            self.trackSplitViewForFirstFlexibleToolbarItem()
        }
    }

    func toolbarDidRemoveItem(_ notification: Notification) {
        trackSplitViewForFirstFlexibleToolbarItem()
    }

    /// - Warning: This is a private Apple method and may break in the future.
    func toolbarDidReorderItem(_ notification: Notification) {
        trackSplitViewForFirstFlexibleToolbarItem()
    }

    /// - Warning: This method uses private Apple methods that may break in the future.
    fileprivate func trackSplitViewForFirstFlexibleToolbarItem() {
        guard var toolbarItems = self.window?.toolbar?.items, let splitView = (contentViewController as? NSSplitViewController)?.splitView else {
            return
        }

        // Add tracking to the first flexible space and remove it from the group
        if let firstFlexibleToolbarItem = toolbarItems.first, firstFlexibleToolbarItem.itemIdentifier == NSToolbarFlexibleSpaceItemIdentifier {
            _ = firstFlexibleToolbarItem.perform(Selector(("setTrackedSplitView:")), with: splitView)
            toolbarItems.removeFirst()
        }

        // Remove tracking from other flexible spaces
        for flexibleToolbarItem in toolbarItems.filter({ $0.itemIdentifier == NSToolbarFlexibleSpaceItemIdentifier }) {
            _ = flexibleToolbarItem.perform(Selector(("setTrackedSplitView:")), with: nil)
        }
    }
}
4

2 に答える 2