NSTabView:工具栏不显示

NSTabView: Toolbar does not display

macOS 10.12.6; Xcode9.3,故事板

我有一个 NSTabView (tabless),它本身包含两个 NSTabView。一种是tabless,另一种使用'toolbar'风格。

当我在工具栏可见的情况下启动我的应用程序时,一切正常:它在工具栏中显示我的选项卡,我可以更改它们,等等。一旦我切换到故事板的另一个分支,工具栏就会消失。 .. 当我回来时,我得到的不是一个带有按钮和所有其他工具栏的工具栏,而是一个略微加宽的栏,其中没有任何内容。

我已经建立了一个示例项目来展示我的问题,其中 - 为了便于切换 - 我留下了另外两个 tabViewController 来显示它们的选项卡(bottom/top,但这没有区别)。

1) 第一个 运行(从 'toolbar' 分支开始): 2)(未显示):切换到'top'分支 3)切换回'toolbar'后:

作为诊断辅助工具,我在 AppController 中创建了一个 'displayToolbarStatus' IBAction:

@IBAction func displayToolbarStatus(_ sender: NSMenuItem){
    if let window = NSApplication.shared.windows.first {
        print(window.toolbar?.isVisible)
    }
}

结果如下: 1)可选(真) 2) 无 3)可选(真)

这非常符合事物的工作方式:工具栏存在并显示,没有工具栏,工具栏存在并显示。当然,它不能用作 作为 工具栏。 (关闭和打开可见性,或尝试使用 window.toolbar?.sizeMode = .regular 强制更改大小没有任何效果,也没有为工具栏项目分配图标;工具栏仍然被压扁并且没有功能按钮。

我还没有深入研究过 NSToolbar:这是一个已知的问题吗?这是 Xcode 9.2 的新功能吗(毕竟,它认为没有 window 是有效的,所以显然在该领域存在一些问题)?

我真的很想使用 NSTabView 'toolbar' 功能:我该如何继续?

我现在有更多时间来使用工具栏。 'weird' 非响应式工具栏的外观只是一个空的工具栏,这让我知道发生了什么事。

0) NSTabView 覆盖了 window 的工具栏;当它消失时,它不会交还控制权;这意味着如果你的 window 中有另一个工具栏,它永远不会在你使用具有 'toolbar' 样式的 NSTabView 时出现。

1) 我在 ToolbarTabViewController 中的每个相关方法中添加了一个打印语句,在包含 TabViewController 的 DidSelect TabViewItem 中添加了一个 'Switching Tabs',以及在工具栏项添加到 window 时进行记录. (ToolbarTabViewController 是包含的 TabViewController 中的第二个控制器;它被选中。否则堆栈看起来略有不同):

ViewDidLoad 
Switching tabs 
viewWillAppear 
viewDidAppear 
Switching tabs
Toolbar will add item 
Toolbar will add item 
viewWillAppear
viewDidAppear

正在切换到另一个选项卡:

viewWillDisappear
Switching tabs
Toolbar did remove item
Toolbar did remove item
viewDidDisappear

到目前为止,还不错。

切换回 ToolbarTabController,我们得到

viewWillAppear
Switching tabs
viewDidAppear

在第一次出现时将与选项卡相关的项目添加到工具栏的任何方法都不会被再次调用。 (另请注意,切换选项卡和 viewDidAppear 的顺序在第一次出现和随后出现时不一致。)

2) 因此,合乎逻辑的做法似乎是捕获正在创建的项目并将它们添加回去以供将来迭代使用。在 ToolbarTabViewController 中:

 var defaultToolbarItems: [NSToolbarItem] = []

    @IBAction  func addTabsBack(_ sender: Any){
            if let window = NSApplication.shared.windows.first {
                if let toolbar = window.toolbar{
                    for (index, item) in defaultToolbarItems.enumerated() {
                        toolbar.insertItem(withItemIdentifier: item.itemIdentifier, at: index)
                    }
                }
            }
        }

override func toolbarWillAddItem(_ notification: Notification) {
       // print("Toolbar will add item")
        if let toolbarItem = notification.userInfo?["item"] as? NSToolbarItem {
            if defaultToolbarItems.count < tabView.numberOfTabViewItems{
                 defaultToolbarItems.append(toolbarItem)
            }
        }
    }

3) 最后一个问题是何时(以及何处)调用 addTabsBack() - 我发现如果我尝试在 viewWillAppear 中调用它,我会从四个 toolbarItems 开始,尽管 tabViewItems 的数量是 2。 (事实上​​,它们似乎是重复的:相同的名称,相同的功能)。因此,我在周围的 TabViewController 的 'didSelect TabViewItem' 方法中调用 addTabsBack() - willSelect 太早了;但 didSelect 恰好为我提供了我需要的功能。

4) 可能有一种更优雅的方法来捕获活动的 toolbarItem,但是现在,我有一个可行的解决方案。