Mac開發(fā)基礎(chǔ)24-NSToolbar
NSToolbar 是 macOS 應(yīng)用中的一個重要控件,用于創(chuàng)建窗口頂部的工具欄。工具欄通常包含按鈕和其他控件,用戶可以通過這些控件快速訪問常用功能。NSToolbar 和 NSToolbarItem 協(xié)同工作,NSToolbar 是工具欄容器,而 NSToolbarItem 是工具欄項。下面我們詳細(xì)介紹 NSToolbar 的常見 API 和基礎(chǔ)技巧。
基本使用
創(chuàng)建和初始化工具欄
Objective-C
#import <Cocoa/Cocoa.h>
// 創(chuàng)建一個 NSToolbar 實例
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"MainToolbar"];
// 設(shè)置 Delegate
[toolbar setDelegate:self];
// 將工具欄添加到窗口
[self.window setToolbar:toolbar];
Swift
import Cocoa
// 創(chuàng)建一個 NSToolbar 實例
let toolbar = NSToolbar(identifier: "MainToolbar")
// 設(shè)置 Delegate
toolbar.delegate = self
// 將工具欄添加到窗口
self.window?.toolbar = toolbar
創(chuàng)建工具欄項
Objective-C
// 實現(xiàn) NSToolbarDelegate 方法,返回所有允許在工具欄中使用的項
- (NSArray<NSString *> *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
return @[@"FirstItem", NSToolbarFlexibleSpaceItemIdentifier, @"SecondItem"];
}
// 實現(xiàn) NSToolbarDelegate 方法,為特定標(biāo)識符創(chuàng)建相應(yīng)的工具欄項
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag {
if ([itemIdentifier isEqualToString:@"FirstItem"]) {
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:@"FirstItem"];
item.label = @"First";
item.toolTip = @"First Tool";
item.action = @selector(handleToolbarAction:);
item.target = self;
item.image = [NSImage imageNamed:NSImageNameAddTemplate];
return item;
} else if ([itemIdentifier isEqualToString:@"SecondItem"]) {
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:@"SecondItem"];
item.label = @"Second";
item.toolTip = @"Second Tool";
item.action = @selector(handleToolbarAction:);
item.target = self;
item.image = [NSImage imageNamed:NSImageNameRemoveTemplate];
return item;
}
return nil;
}
Swift
// 實現(xiàn) NSToolbarDelegate 方法,返回所有允許在工具欄中使用的項
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [.init("FirstItem"), .flexibleSpace, .init("SecondItem")]
}
// 實現(xiàn) NSToolbarDelegate 方法,為特定標(biāo)識符創(chuàng)建相應(yīng)的工具欄項
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
if itemIdentifier.rawValue == "FirstItem" {
let item = NSToolbarItem(itemIdentifier: .init("FirstItem"))
item.label = "First"
item.toolTip = "First Tool"
item.action = #selector(handleToolbarAction(_:))
item.target = self
item.image = NSImage(named: NSImage.addTemplateName)
return item
} else if itemIdentifier.rawValue == "SecondItem" {
let item = NSToolbarItem(itemIdentifier: .init("SecondItem"))
item.label = "Second"
item.toolTip = "Second Tool"
item.action = #selector(handleToolbarAction(_:))
item.target = self
item.image = NSImage(named: NSImage.removeTemplateName)
return item
}
return nil
}
響應(yīng)工具欄項點擊事件
Objective-C
// 實現(xiàn)工具欄項的點擊響應(yīng)方法
- (void)handleToolbarAction:(id)sender {
NSToolbarItem *selectedItem = (NSToolbarItem *)sender;
NSLog(@"Selected item: %@", selectedItem.itemIdentifier);
}
Swift
// 實現(xiàn)工具欄項的點擊響應(yīng)方法
@objc func handleToolbarAction(_ sender: Any?) {
if let toolbarItem = sender as? NSToolbarItem {
print("Selected item: \(toolbarItem.itemIdentifier.rawValue)")
}
}
自定義工具欄項
可以通過子類化 NSToolbarItem 來創(chuàng)建自定義工具欄項。
Objective-C
@interface CustomToolbarItem : NSToolbarItem
@end
@implementation CustomToolbarItem
- (instancetype)initWithItemIdentifier:(NSString *)itemIdentifier {
self = [super initWithItemIdentifier:itemIdentifier];
if (self) {
// 自定義設(shè)置
self.label = @"Custom";
self.toolTip = @"Custom Tool";
self.image = [NSImage imageNamed:NSImageNameInfo];
}
return self;
}
@end
Swift
class CustomToolbarItem: NSToolbarItem {
override init(itemIdentifier: NSToolbarItem.Identifier) {
super.init(itemIdentifier: itemIdentifier)
// 自定義設(shè)置
self.label = "Custom"
self.toolTip = "Custom Tool"
self.image = NSImage(named: NSImage.infoTemplateName)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
動態(tài)更新工具欄項
可以通過設(shè)置工具欄項的 minSize 和 maxSize 以及使用 validateToolbarItem 方法來動態(tài)更新工具欄項。
Objective-C
- (BOOL)validateToolbarItem:(NSToolbarItem *)toolbarItem {
if ([toolbarItem.itemIdentifier isEqualToString:@"FirstItem"]) {
// 根據(jù)條件禁用或啟用工具欄項
return YES;
}
return YES;
}
// 更新工具欄項的大小
- (void)updateToolbarItemsSize {
NSToolbarItem *firstItem = [self.toolbar.items firstObject];
[firstItem setMinSize:NSMakeSize(30, 30)];
[firstItem setMaxSize:NSMakeSize(50, 50)];
}
Swift
func validateToolbarItem(_ item: NSToolbarItem) -> Bool {
if item.itemIdentifier.rawValue == "FirstItem" {
// 根據(jù)條件禁用或啟用工具欄項
return true
}
return true
}
// 更新工具欄項的大小
func updateToolbarItemsSize() {
if let firstItem = toolbar.items.first {
firstItem.minSize = NSSize(width: 30, height: 30)
firstItem.maxSize = NSSize(width: 50, height: 50)
}
}
隱藏和顯示工具欄
可以通過 setVisible: 方法控制工具欄的顯示和隱藏。
Objective-C
// 隱藏工具欄
[self.window.toolbar setVisible:NO];
// 顯示工具欄
[self.window.toolbar setVisible:YES];
Swift
// 隱藏工具欄
self.window?.toolbar?.isVisible = false
// 顯示工具欄
self.window?.toolbar?.isVisible = true
高級用法
自定義工具欄項視圖
可以自定義工具欄項的視圖,比如將 NSButton 作為工具欄項。
Objective-C
- (NSToolbarItem *)createCustomViewToolbarItemWithIdentifier:(NSString *)identifier label:(NSString *)label action:(SEL)action {
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:identifier];
item.label = label;
item.view = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 30)];
NSButton *button = (NSButton *)item.view;
[button setTitle:label];
[button setTarget:self];
[button setAction:action];
return item;
}
Swift
func createCustomViewToolbarItem(identifier: NSToolbarItem.Identifier, label: String, action: Selector) -> NSToolbarItem {
let item = NSToolbarItem(itemIdentifier: identifier)
item.label = label
let button = NSButton(frame: NSRect(x: 0, y: 0, width: 100, height: 30))
button.title = label
button.target = self
button.action = action
item.view = button
return item
}
動態(tài)添加和移除工具欄項
Objective-C
// 動態(tài)添加工具欄項
- (void)addToolbarItemWithIdentifier:(NSString *)identifier {
NSToolbarItem *newItem = [self toolbar:nil itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];
[self.toolbar insertItemWithItemIdentifier:identifier atIndex:self.toolbar.items.count];
}
// 動態(tài)移除工具欄項
- (void)removeToolbarItemWithIdentifier:(NSString *)identifier {
for (NSToolbarItem *item in self.toolbar.items) {
if ([item.itemIdentifier isEqualToString:identifier]) {
[self.toolbar removeItemAtIndex:[self.toolbar.items indexOfObject:item]];
break;
}
}
}
Swift
// 動態(tài)添加工具欄項
func addToolbarItem(identifier: NSToolbarItem.Identifier) {
if let newItem = self.toolbar(nil, itemForItemIdentifier: identifier, willBeInsertedIntoToolbar: true) {
toolbar.insertItem(withItemIdentifier: identifier, at: toolbar.items.count)
}
}
// 動態(tài)移除工具欄項
func removeToolbarItem(identifier: NSToolbarItem.Identifier) {
for (item in toolbar.items) {
if item.itemIdentifier == identifier {
if let index = toolbar.items.firstIndex(of: item) {
toolbar.removeItem(at: index)
break
}
}
}
}
工具欄定制面板
macOS 提供了工具欄定制功能,用戶可以通過它自行選擇工具欄中的項。
Objective-C
// 允許工具欄定制
[toolbar setAllowsUserCustomization:YES];
// 實現(xiàn)代理方法,返回用戶定制時可以看到的項
- (NSArray<NSString *> *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
return @[@"FirstItem", NSToolbarFlexibleSpaceItemIdentifier, @"SecondItem"];
}
- (NSArray<NSString *> *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
return @[@"FirstItem", NSToolbarFlexibleSpaceItemIdentifier, @"SecondItem", @"CustomItem"];
}
Swift
// 允許工具欄定制
toolbar.allowsUserCustomization = true
// 實現(xiàn)代理方法,返回用戶定制時可以看到的項
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [.init("FirstItem"), .flexibleSpace, .init("SecondItem")]
}
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [.init("FirstItem"), .flexibleSpace, .init("SecondItem"), .init("CustomItem")]
}
封裝工具類
為了更方便地使用 NSToolbar,可以封裝一個工具類,提供常見功能的高層接口。
Objective-C
#import <Cocoa/Cocoa.h>
@interface NSToolbarHelper : NSObject
+ (NSToolbar *)createToolbarWithIdentifier:(NSString *)identifier delegate:(id<NSToolbarDelegate>)delegate;
+ (NSToolbarItem *)createToolbarItemWithIdentifier:(NSString *)identifier label:(NSString *)label action:(SEL)action target:(id)target image:(NSImage *)image;
@end
@implementation NSToolbarHelper
+ (NSToolbar *)createToolbarWithIdentifier:(NSString *)identifier delegate:(id<NSToolbarDelegate>)delegate {
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:identifier];
[toolbar setDelegate:delegate];
[toolbar setAllowsUserCustomization:YES];
return toolbar;
}
+ (NSToolbarItem *)createToolbarItemWithIdentifier:(NSString *)identifier label:(NSString *)label action:(SEL)action target:(id)target image:(NSImage *)image {
NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:identifier];
item.label = label;
item.toolTip = label;
item.image = image;
item.action = action;
item.target = target;
return item;
}
@end
Swift
import Cocoa
class NSToolbarHelper {
// 創(chuàng)建 NSToolbar 并設(shè)置代理
static func createToolbar(identifier: String, delegate: NSToolbarDelegate) -> NSToolbar {
let toolbar = NSToolbar(identifier: NSToolbar.Identifier(identifier))
toolbar.delegate = delegate
toolbar.allowsUserCustomization = true
return toolbar
}
// 創(chuàng)建 NSToolbarItem
static func createToolbarItem(identifier: String, label: String, action: Selector, target: AnyObject, image: NSImage) -> NSToolbarItem {
let item = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier(identifier))
item.label = label
item.toolTip = label
item.image = image
item.action = action
item.target = target
return item
}
}
使用示例
Objective-C
// 創(chuàng)建 NSToolbar
NSToolbar *toolbar = [NSToolbarHelper createToolbarWithIdentifier:@"MainToolbar" delegate:self];
[self.window setToolbar:toolbar];
// 創(chuàng)建并添加工具欄項
NSToolbarItem *firstItem = [NSToolbarHelper createToolbarItemWithIdentifier:@"FirstItem" label:@"First" action:@selector(handleToolbarAction:) target:self image:[NSImage imageNamed:NSImageNameAddTemplate]];
[toolbar insertItemWithItemIdentifier:@"FirstItem" atIndex:0];
NSToolbarItem *secondItem = [NSToolbarHelper createToolbarItemWithIdentifier:@"SecondItem" label:@"Second" action:@selector(handleToolbarAction:) target:self image:[NSImage imageNamed:NSImageNameRemoveTemplate]];
[toolbar insertItemWithItemIdentifier:@"SecondItem" atIndex:1];
Swift
// 創(chuàng)建 NSToolbar
let toolbar = NSToolbarHelper.createToolbar(identifier: "MainToolbar", delegate: self)
self.window?.toolbar = toolbar
// 創(chuàng)建并添加工具欄項
let firstItem = NSToolbarHelper.createToolbarItem(identifier: "FirstItem", label: "First", action: #selector(handleToolbarAction(_:)), target: self, image: NSImage(named: NSImage.addTemplateName)!)
toolbar.insertItem(withItemIdentifier: NSToolbarItem.Identifier("FirstItem"), at: 0)
let secondItem = NSToolbarHelper.createToolbarItem(identifier: "SecondItem", label: "Second", action: #selector(handleToolbarAction(_:)), target: self, image: NSImage(named: NSImage.removeTemplateName)!)
toolbar.insertItem(withItemIdentifier: NSToolbarItem.Identifier("SecondItem"), at: 1)
總結(jié)
通過了解 NSToolbar 的基本使用、創(chuàng)建工具欄項、響應(yīng)工具欄項選擇、自定義工具欄項、動態(tài)更新工具欄項、隱藏和顯示工具欄以及工具欄定制面板等高級用法,并封裝工具類,你將能夠更高效地使用 NSToolbar 創(chuàng)建復(fù)雜的工具欄系統(tǒng)。在實際應(yīng)用中,合理使用這些技巧可以顯著提升用戶界面的靈活性和用戶體驗。希望本文對你有所幫助,
將來的你會感謝今天如此努力的你!
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。

浙公網(wǎng)安備 33010602011771號