在NSToolbar中实现NSSegmentedControl来控制NSTabViewController

时间:2017-08-15 07:53:42

标签: macos cocoa nstoolbar nstabview nssegmentedcontrol

在我的macOS应用程序中,我尝试复制NSSegmentedControlNSToolbar的Photos.app实现来控制NSTabViewController。作为参考,这里看起来像:

Photos.app in macOS Sierra.

所以,我的方法如下:

  1. 使用Interface Builder
  2. 隐藏默认的NSTabView标头
  3. 以编程方式添加NSToolbar
  4. NSSegmentedControl作为NSToolbarItem插入。
  5. 使用#selector收听NSSegmentedControl
  6. 的更改

    这是当前的实施:

    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
            }
        }
    
    }
    

    而且,这是在行动:

    Implementing NSSegmentedControl in NSToolbar to control NSTabViewController.

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

    感谢您的时间。

1 个答案:

答案 0 :(得分:1)

enter image description here对于在工具栏上实现NSSegmentedControl且未触发IBAction的任何人,我都遇到了同样的问题,花了我半天的时间来解决。 问题是我将分段与NSWindowController类连接。

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