Finder和Notes具有我正在寻求重现的特有行为。 NSToolbar中的'灵活空间'似乎考虑了分割视图的尺寸。例如,第一组按钮在左侧与侧边栏的右侧对齐。第二组图标与第一列的右侧对齐。当我扩大边栏时,工具栏内容随之移动。将NSToolbarItems与NSSplitView列对齐
这有可能重现吗?
解决方案
与@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)
}
}
}
太棒了,这似乎工作。两个注释:(1)'toolbarWillAddItem:'需要稍微不同的行为,因为当调用此方法时,工具栏项不会更新。应该直接在这个网络项上调用'setTrackedSplitView:'。 (2)将其余项目设置为零会导致不稳定的行为以及种类“无法识别的选择器”的错误。 – Eitot
您应该只设置剩余的**灵活空间**项目以跟踪'nil'。我假设,在这个引擎盖下,这些项目有一个特定的子类。您需要清除已跟踪的分割视图,因为您可能先前已将其设置为其中一个视图,然后他们更改了顺序。关于'-toolbarWillAddItem:',我的代码会使用'dispatch_async()'将主体队列中的项目更新推迟到运行循环结束。 –
在DispatchQueue.main.async()中调用它只在应用程序运行时才在我的代码中工作,但在启动时它似乎不起作用。你能举一个你如何实现这个的例子吗? – Eitot