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 的(如下图)。 本文是关于如何在自己的程序中实现这个。
开发环境如下:
Xcode: 11.0
Swift: 4
minimum macOS deployment target: 10.13.
1. 绑定 Window Controller
新建的 Xcode Cocoa app 项目的根目录都有一个 Main.storyboard
,
现在我们来给它绑定一个 Controller, 用于后面添加 Toolbar
- 新建一个类,继承 NSWindowController.
- 在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.备注
- 以下代码可以去掉 Toolbar 上按钮的标题
toolbar.displayMode = .iconOnly
- NSToolbar 的
init()
构造函数需要 macOS 10.13+, 另一个没有SDK版本限制的是init(identifier: NSToolbar.Identifier)
- NSImage.XXXTemplateName 常量需要 macOS 10.12+
本文地址:https://blog.csdn.net/joelcat/article/details/107102710