欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

macOS: 前进与返回按钮

程序员文章站 2022-05-06 21:53:18
在macOS 上有许多程序都提供一个前进或返回按钮,例如 Finder 的(如下图)。 本文是关于如何在自己的程序中实现这个。开发环境如下:Xcode: 11.0Swift: 4minimum macOS deployment target: 10.13.1. 绑定 Window Controller新建的 Xcode Cocoa app 项目的根目录都有一个 Main.storyboard,现在我们来给它绑定一个 Controller, 用于后面添加 Toolbar新建一个类,继承...

在macOS 上有许多程序都提供一个前进返回按钮,例如 Finder 的(如下图)。 本文是关于如何在自己的程序中实现这个。
macOS: 前进与返回按钮

开发环境如下:

Xcode: 11.0
Swift: 4
minimum macOS deployment target: 10.13.

1. 绑定 Window Controller

新建的 Xcode Cocoa app 项目的根目录都有一个 Main.storyboard,
现在我们来给它绑定一个 Controller, 用于后面添加 Toolbar

  1. 新建一个类,继承 NSWindowController.
  2. 在Main.storyboard 中的 Window Controller Scene 中绑定

MyWindowController.swift

import Cocoa

class MyWindowController: NSWindowController {
    override func windowDidLoad() {
        
    }
}

绑定示意图:

macOS: 前进与返回按钮

2. 给App添加工具栏

现在,我们在 MyWindowController 中用代码实现 给App添加工具栏,并把代理(NSToolbarDelegate) 绑定到这个类上。

MyWindowController.swift

import Cocoa

class MyWindowController: NSWindowController, NSToolbarDelegate {
    var toolbar: NSToolbar!
    
    override func windowDidLoad() {
        toolbar = NSToolbar()
        toolbar.delegate = self;
        self.window!.toolbar = toolbar;
    }
    
    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        return nil;
    }

    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [];
    }

    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [];
    }

    func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [];
    }

    func toolbarWillAddItem(_ notification: Notification) {
        
    }

    func toolbarDidRemoveItem(_ notification: Notification) {
        
    }
}

现在,我们已经成功为当前窗口添加了一个工具栏。不过目前我们的工具栏上什么也没有,只能看见窗口的顶部变高了许多。

没有任何类容的工具栏 (下图)

macOS: 前进与返回按钮

3. 添加前进和后退按钮

下面的代码展示了如何添加一个前进和后退按钮在 Toolbar 上。

import Cocoa

class MyWindowController: NSWindowController, NSToolbarDelegate {
    var toolbar: NSToolbar!
    
    let back_forward_segment = "back_forward_segment"
    override func windowDidLoad() {
        toolbar = NSToolbar()
        toolbar.delegate = self;
        self.window!.toolbar = toolbar;
    }
    
    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        if itemIdentifier.rawValue != back_forward_segment {
            return nil;
        }
        
        let itemA = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier(rawValue: "BackToolbarItem"))
        itemA.label = "Back"
        itemA.action = #selector(goBack) // bind click action
        let itemB = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier(rawValue: "ForwardToolbarItem"))
        itemB.label = "Forward"
        itemB.action = #selector(goForward)

        let segmented = NSSegmentedControl(frame: NSRect(x: 0, y: 0, width: 40, height: 20))
        segmented.segmentStyle = .texturedRounded
        segmented.trackingMode = .momentary
        segmented.segmentCount = 2
        segmented.setImage(NSImage(named: NSImage.goBackTemplateName)!, forSegment: 0)
        segmented.setWidth(20, forSegment: 0)
        segmented.setImage(NSImage(named: NSImage.goForwardTemplateName)!, forSegment: 1)
        segmented.setWidth(20, forSegment: 1)
        
        let group = NSToolbarItemGroup(itemIdentifier: itemIdentifier)
        group.paletteLabel = "Navigation"
        group.subitems = [itemA, itemB]
        group.view = segmented
        
        return group;
    }

    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [NSToolbarItem.Identifier(back_forward_segment)];
    }

    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [NSToolbarItem.Identifier(back_forward_segment)];
    }

    func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
        return [];
    }

    func toolbarWillAddItem(_ notification: Notification) {
        
    }

    func toolbarDidRemoveItem(_ notification: Notification) {
        
    }
    
    // ------------------------------------------------------------------------------------------
    
    @objc func goBack() {
        print("click go back")
    }
    
    @objc func goForward() {
        print("click go forward")
    }
}

完成后的效果图(下图):

macOS: 前进与返回按钮

值得注意的是,func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) 函数没有返回有效的数据。
如果上面的例子中返回了 back_forward_segment 的话,那么当前进或后退按钮点击时,这个按钮所在的组会出现一个被选中背景(灰色)。

4.备注

  1. 以下代码可以去掉 Toolbar 上按钮的标题
toolbar.displayMode = .iconOnly
  1. NSToolbar 的 init() 构造函数需要 macOS 10.13+, 另一个没有SDK版本限制的是 init(identifier: NSToolbar.Identifier)
  2. NSImage.XXXTemplateName 常量需要 macOS 10.12+

本文地址:https://blog.csdn.net/joelcat/article/details/107102710