0

macOS 10.12.6;Xcode 9.3,故事板

我有一个 NSTabView (tabless),它本身包含两个 NSTabViews。一种是tabless,另一种使用“工具栏”样式。

当我在工具栏可见的情况下启动我的应用程序时,一切都很好:它在工具栏中显示我的选项卡,我可以更改它们等等。一旦我更改到情节提要的另一个分支,工具栏就会消失......当我回来,而不是适当的工具栏,带有按钮和所有这些,我得到一个稍微加宽的栏,其中没有任何内容。

我已经设置了一个示例项目来显示我的问题,其中 - 为了便于切换 - 我让其他两个 tabViewControllers 来显示它们的选项卡(底部/顶部,但这没有区别)。

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) optional(true) 2) nil 3) optional(true)

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

我没有深入使用 NSToolbar:这是一个已知的解决方法吗?这是 Xcode 9.2 的新功能(毕竟,它认为没有窗口是有效的,所以显然在那个领域有一些问题)?

我真的很想使用 NSTabView 的“工具栏”功能:我该如何进行?

4

1 回答 1

0

我现在有更多时间玩工具栏了。非响应工具栏的“奇怪”外观只是一个空工具栏,这让我知道发生了什么。

0) NSTabView 覆盖窗口的工具栏;当它消失时,它不会交还控制权;这意味着如果您的窗口中有另一个工具栏,当您使用具有“工具栏”样式的 NSTabView 时,该工具栏将永远不会出现。

1) 我在 ToolbarTabViewController 中的每个相关方法中添加了一个打印语句,并在包含 TabViewController 的 DidSelect TabViewItem 中添加了一个“切换选项卡”,以及在将工具栏项添加到窗口时进行记录。(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 中调用它,我会从四个工具栏项开始,尽管 tabViewItems 的数量是 2。(事实上,它们似乎重复:相同的名称,相同的功能)。因此,我addTabsBack()在周围的 TabViewController 的 'didSelect TabViewItem' 方法中调用了 - willSelect 为时过早;但是 didSelect 给了我我需要的功能。

4) 可能有一种更优雅的方式来捕获活动的工具栏项,但现在,我有一个可行的解决方案。

于 2018-01-26T01:04:02.910 回答