【问题标题】:NSTabView: Toolbar does not displayNSTabView:工具栏不显示
【发布时间】:2018-01-03 12:38:16
【问题描述】:

macOS 10.12.6; Xcode 9.3,故事板

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

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

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

1) 首次运行(从“工具栏”分支开始): 2)(未显示):切换到“顶部”分支 3)切换回“工具栏”后:

作为诊断辅助,我在 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 的新功能(毕竟,它认为没有窗口是有效的,因此显然在该领域存在一些问题)?

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

【问题讨论】:

  • 来自文档:“NSTabViewControllerTabStyleToolbar:一种自动将任何选项卡添加到窗口工具栏的样式。选项卡视图控制器控制窗口的工具栏并将自己设置为工具栏的代表。”。我认为 Apple 没有测试您的配置,因为这不是工具栏和选项卡视图的使用方式。
  • @Willeke:我不明白你从哪里得出结论。在其他地方(故事板文档),Apple 声明“在 macOS 中,包含(而不是转换)是故事板更常见的概念”,并且表格样式表明 NSTabViews 旨在指导应用程序流程。它似乎没有添加,它似乎被覆盖,即使 TabViewController 是主(包含 tabBar)窗口的 contentViewController。
  • 为什么要嵌套标签视图?表格标签视图可以提供您自己的控件。你把这些控件放在哪里?当控制 tabviewcontroller 被释放时,工具栏应该发生什么?覆盖与“控制”相同?
  • 1) 我嵌套了 tabview,因为我有一个复杂的应用程序,其中包含多个逻辑分支,并且使用 tabViews 是比重新发明它们更好的解决方案。 2) 由于控制器由 tabViewController 持有,因此在窗口关闭之前它不会被释放(我通过添加 deinit 方法进行了检查)。 3)我可以看到你来自哪里,但我没有这样解释; “替换”会更清楚。

标签: macos nstoolbar nstabview


【解决方案1】:

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

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

在第一次出现时将与选项卡相关的项目添加到工具栏的任何方法都不会再次被调用。 (还要注意,第一次出现和后面出现的切换tab和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。(他们确实这样做了,实际上,似乎是重复的:相同的名称,相同的功能)。因此,我在周围的 TabViewController 的 'didSelect TabViewItem' 方法中调用addTabsBack() - willSelect 为时过早;但 didSelect 给了我我需要的功能。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-06
    • 2014-04-21
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多