Align NSToolbarItems with NSSplitView columns

后端 未结 2 646
温柔的废话
温柔的废话 2021-01-03 04:48

Finder and Notes have a peculiar behaviour that I am seeking to reproduce. The ‘flexible space’ in the NSToolbar seems to take the dimensions of the split view into account.

2条回答
  •  时光说笑
    2021-01-03 05:12

    When using macOS 11 or newer, you can insert NSTrackingSeparatorToolbarItem items to the toolbar, which will split up your toolbar in sections, aligned with the dividers of a NSSplitView object.

    This example adds the new separator items to a toolbar that already contains the rest of the buttons, configured in Interface Builder or in code. The target splitview concerns a standard configuration of 3 splitviews, including a sidebar panel.

    class WindowController: NSWindowController, NSToolbarDelegate {
    
        let mainPanelSeparatorIdentifier = NSToolbarItem.Identifier(rawValue: "MainPanel")
    
        override func windowDidLoad() {
            super.windowDidLoad()
    
            self.window?.toolbar?.delegate = self
        
            // Calling the inserts async gives more time to bind with the split viewer, and prevents crashes
            DispatchQueue.main.async {
    
                // The .sidebarTrackingSeparator is a built-in tracking separator which always aligns with the sidebar splitview
                self.window?.toolbar?.insertItem(withItemIdentifier: .sidebarTrackingSeparator, at: 0)
            
                // Example of a custom mainPanelSeparatorIdentifier
                // Index at '3' means that there are 3 toolbar items at the left side
                // of this separator, including the first tracking separator
                self.window?.toolbar?.insertItem(withItemIdentifier: mainPanelSeparatorIdentifier at: 3)
            }
        }
    
        func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        
            if let splitView = (self.contentViewController as? NSSplitViewController)?.splitView {
            
                // You must implement this for custom separator identifiers, to connect the separator with a split view divider
                if itemIdentifier == mainPanelSeparatorIdentifier {
                    return NSTrackingSeparatorToolbarItem(identifier: itemIdentifier, splitView: splitView, dividerIndex: 1)
                }
            }
            return nil
        }
    }
    

提交回复
热议问题