当前位置: 移动技术网 > 移动技术>移动开发>Android > macOS: 前进与返回按钮

macOS: 前进与返回按钮

2020年07月08日  | 移动技术网移动技术  | 我要评论

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

开发环境如下:

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() {
        
    }
}

绑定示意图:

在这里插入图片描述

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

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

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

在这里插入图片描述

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

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

在这里插入图片描述

值得注意的是,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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网