4

在我的 macOS 应用程序中,我试图复制 in 的 Photos.app 实现NSSegmentedControlNSToolbar控制NSTabViewController. 作为参考,下面是它的样子:

macOS Sierra 中的 Photos.app。

所以,我的方法如下:

  1. 使用 Interface Builder隐藏默认NSTabView标题
  2. 以编程方式添加NSToolbar
  3. 插入NSSegmentedControlNSToolbarItem.
  4. 使用 a#selector监听对 的更改NSSegmentedControl

这是当前的实现:

class WindowController: NSWindowController, NSToolbarDelegate {

    // MARK: - Identifiers

    let mainToolbarIdentifier = NSToolbar.Identifier("MAIN_TOOLBAR")
    let segmentedControlIdentifier = NSToolbarItem.Identifier("MAIN_TABBAR")

    // MARK: - Properties

    var tabBar: NSSegmentedControl? = NSSegmentedControl(labels: ["One", "Two"], trackingMode: NSSegmentedControl.SwitchTracking.selectOne, target: self, action: #selector(didSwitchTabs))
    var toolbar: NSToolbar?
    var tabBarController: NSTabViewController?

    // MARK: - Life Cycle

    override func windowDidLoad() {
        super.windowDidLoad()

        self.toolbar = NSToolbar(identifier: mainToolbarIdentifier)
        self.toolbar?.allowsUserCustomization = false
        self.toolbar?.delegate = self

        self.tabBar?.setSelected(true, forSegment: 0)

        self.tabBarController = self.window?.contentViewController as? NSTabViewController
        self.tabBarController?.selectedTabViewItemIndex = 0

        self.window?.toolbar = self.toolbar
    }

    // MARK: - NSToolbarDelegate

    public func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {

        var toolbarItem: NSToolbarItem

        switch itemIdentifier {
        case segmentedControlIdentifier:
            toolbarItem = NSToolbarItem(itemIdentifier: segmentedControlIdentifier)
            toolbarItem.view = self.tabBar
        case NSToolbarItem.Identifier.flexibleSpace:
            toolbarItem = NSToolbarItem(itemIdentifier: itemIdentifier)
        default:
            fatalError()
        }

        return toolbarItem
    }

    public func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [segmentedControlIdentifier, NSToolbarItem.Identifier.flexibleSpace]
    }

    public func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [NSToolbarItem.Identifier.flexibleSpace, segmentedControlIdentifier, NSToolbarItem.Identifier.flexibleSpace]
    }

    // MARK: - Selectors

    @objc func didSwitchTabs(sender: Any) {

        let segmentedControl = sender as! NSSegmentedControl

        if (segmentedControl.selectedSegment == 0) {
            self.tabBarController?.selectedTabViewItemIndex = 0
        } else if (segmentedControl.selectedSegment == 1) {
            self.tabBarController?.selectedTabViewItemIndex = 1
        }
    }

}

而且,它正在发挥作用:

在 NSToolbar 中实现 NSSegmentedControl 来控制 NSTabViewController。

现在,我是 macOS 开发的新手,感觉这是解决这个问题的一种非常复杂和令人费解的方式。有没有更简单的方法可以实现同样的目标?也许在 Interface Builder 中以某种方式?可以做些什么来改进这里?我做错了什么?

谢谢你的时间。

4

1 回答 1

1

在此处输入图像描述对于在工具栏上实现 NSSegmentedControl 并且它没有触发 IBAction 的任何人,我遇到了同样的问题并支付了半天的时间来解决这个问题。问题是我将分段与 NSWindowController 类连接起来。

要解决此问题,请创建 NSWindow 的子类,将该类设置为情节提要上窗口的基类,然后创建 @IBOutlet @IBAction 到 NSWindow 的链接。请记住,将其与 NSWindowController 链接将不起作用。

于 2020-05-13T03:26:45.247 回答