将NSToolbarItems与NSSplitView列对齐 [英] Align NSToolbarItems with NSSplitView columns

查看:194
本文介绍了将NSToolbarItems与NSSplitView列对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Finder和Notes具有我要重现的特殊行为. NSToolbar中的灵活空间"似乎考虑了拆分视图的尺寸.例如,第一组按钮在侧栏的左侧与右侧对齐.第二组图标与第一列的右侧对齐.当我加宽侧边栏时,工具栏项会随之移动.

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. For instance, the first group of buttons aligns on the left side with the right side of the sidebar. The second group of icons aligns with the right side of the first column. When I widen the sidebar, the toolbar items move along with it.

可以重现吗?

使用@KenThomases提供的解决方案,我已经实现了以下步骤:

With the solution provided by @KenThomases, I have implemented this as follows:

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)
        }
    }
}

推荐答案

您可以使用Apple私有方法来执行此操作,尽管App Store不允许这样做.

You can do this with Apple-private methods, although that's not allowed in the App Store.

NSToolbarItem上有一个私有方法-setTrackedSplitView:.它以NSSplitView*作为其参数.您需要在要跟踪拆分视图的灵活空间工具栏项上调用它,并将其传递给应该跟踪的拆分视图.为了保护自己免受Apple删除该方法的影响,您应在尝试使用该方法之前检查NSToolbarItem是否响应该方法.

There's a private method, -setTrackedSplitView:, on NSToolbarItem. It takes an NSSplitView* as its parameter. You need to call it on the flexible-space toolbar item that you want to track a split view and pass it the split view it should track. To protect yourself against Apple removing the method, you should check if NSToolbarItem responds to the method before trying to use it.

由于用户可以自定义工具栏并对其进行重新排序,因此通常需要枚举窗口工具栏的项目.对于第一个标识符为NSToolbarFlexibleSpaceItemIdentifier的标识符,您可以设置它应跟踪的拆分视图.对于所有其他灵活空间项目,您清除(设置为nil)要跟踪的拆分视图.您需要在第一次设置窗口时再次执行此操作,然后再次在工具栏委托的-toolbarWillAddItem:-toolbarDidRemoveItem:方法中进行设置.还有另一个未公开的委托方法-toolbarDidReorderItem:,在这里我发现它对更新工具栏很有用.

Since the user can customize and re-order the toolbar, you generally need to enumerate the window's toolbar's items. For the first one whose identifier is NSToolbarFlexibleSpaceItemIdentifier, you set the split view it should track. For all other flexible-space items, you clear (set to nil) the split view to track. You need to do that when the window is first set up and again in the toolbar delegate's -toolbarWillAddItem: and -toolbarDidRemoveItem: methods. There's also another undocumented delegate method, -toolbarDidReorderItem:, where I've found it useful to update the toolbar.

这篇关于将NSToolbarItems与NSSplitView列对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆