gpt4 book ai didi

cocoa - 将 NSToolbarItems 与 NSSplitView 列对齐

转载 作者:行者123 更新时间:2023-12-03 16:14:23 28 4
gpt4 key购买 nike

Finder 和 Notes 有一个我正在寻求重现的特殊行为。 NSToolbar 中的“灵活空间”似乎考虑了分割 View 的尺寸。例如,第一组按钮在侧边栏的左侧与右侧对齐。第二组图标与第一列的右侧对齐。当我加宽侧边栏时,工具栏项目也会随之移动。

可以重现这个吗?

enter image description here

<小时/>

解决方案

根据@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)
}
}
}

最佳答案

使用 macOS 11 或更高版本时,您可以将 NSTrackingSeparatorToolbarItem 项插入到工具栏,这会将工具栏分成几个部分,并与 NSSplitView 对象的分隔线对齐.

此示例将新的分隔符项添加到已包含在 Interface Builder 或代码中配置的其余按钮的工具栏中。目标分割 View 涉及 3 个分割 View 的标准配置,包括侧边栏面板。

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

如果您想添加额外的分隔符(例如,为检查器面板),只需将附加的工具栏项目标识符插入到工具栏,然后将额外的 NSTrackingSeparatorToolbarItem 分配给 中的另一个分隔符itemForItemIdentifier 委托(delegate)函数。

关于cocoa - 将 NSToolbarItems 与 NSSplitView 列对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41372245/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com