Mac開發(fā)基礎(chǔ)22-NSTabView
NSTabView 是 macOS 應(yīng)用中的一個重要控件,用于創(chuàng)建帶有多個選項卡的界面,類似于網(wǎng)頁瀏覽器的選項卡功能。它能夠?qū)⒍鄠€視圖容器合并到一個控件中,每個視圖容器都可以通過選項卡來切換。
基本使用
創(chuàng)建和初始化
Objective-C
#import <Cocoa/Cocoa.h>
// 創(chuàng)建一個 NSTabView 實例
NSTabView *tabView = [[NSTabView alloc] initWithFrame:NSMakeRect(0, 0, 600, 400)];
Swift
import Cocoa
// 創(chuàng)建一個 NSTabView 實例
let tabView = NSTabView(frame: NSRect(x: 0, y: 0, width: 600, height: 400))
添加標(biāo)簽頁
Objective-C
// 創(chuàng)建第一個 TabViewItem
NSTabViewItem *firstTab = [[NSTabViewItem alloc] initWithIdentifier:@"firstTab"];
[firstTab setLabel:@"First Tab"]; // 設(shè)置標(biāo)簽頁名稱
NSView *firstView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 600, 400)];
[firstView setWantsLayer:YES];
[firstView.layer.backgroundColor = [NSColor redColor].CGColor];
[firstTab setView:firstView];
// 創(chuàng)建第二個 TabViewItem
NSTabViewItem *secondTab = [[NSTabViewItem alloc] initWithIdentifier:@"secondTab"];
[secondTab setLabel:@"Second Tab"]; // 設(shè)置標(biāo)簽頁名稱
NSView *secondView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 600, 400)];
[secondView setWantsLayer:YES];
[secondView.layer.backgroundColor = [NSColor blueColor].CGColor];
[secondTab setView:secondView];
// 將標(biāo)簽頁添加到 TabView
[tabView addTabViewItem:firstTab];
[tabView addTabViewItem:secondTab];
Swift
// 創(chuàng)建第一個 TabViewItem
let firstTab = NSTabViewItem(identifier: "firstTab")
firstTab.label = "First Tab" // 設(shè)置標(biāo)簽頁名稱
let firstView = NSView(frame: NSRect(x: 0, y: 0, width: 600, height: 400))
firstView.wantsLayer = true
firstView.layer?.backgroundColor = NSColor.red.cgColor
firstTab.view = firstView
// 創(chuàng)建第二個 TabViewItem
let secondTab = NSTabViewItem(identifier: "secondTab")
secondTab.label = "Second Tab" // 設(shè)置標(biāo)簽頁名稱
let secondView = NSView(frame: NSRect(x: 0, y: 0, width: 600, height: 400))
secondView.wantsLayer = true
secondView.layer?.backgroundColor = NSColor.blue.cgColor
secondTab.view = secondView
// 將標(biāo)簽頁添加到 TabView
tabView.addTabViewItem(firstTab)
tabView.addTabViewItem(secondTab)
數(shù)據(jù)源和委托
NSTabView 使用委托(NSTabViewDelegate)來處理標(biāo)簽頁的選擇和其他事件。
Objective-C
// 設(shè)置代理
[tabView setDelegate:self];
// 實現(xiàn)代理方法,當(dāng)選擇不同標(biāo)簽頁時調(diào)用
- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem {
NSLog(@"Selected tab: %@", tabViewItem.label); // 處理標(biāo)簽頁選擇事件
}
Swift
// 設(shè)置代理
tabView.delegate = self
// 實現(xiàn)代理方法,當(dāng)選擇不同標(biāo)簽頁時調(diào)用
func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
if let tabViewItem = tabViewItem {
print("Selected tab: \(tabViewItem.label)") // 處理標(biāo)簽頁選擇事件
}
}
使用自動布局
NSTabView 也支持自動布局,這使得調(diào)整窗口大小時標(biāo)簽頁內(nèi)容能夠更好地適應(yīng)變化。
Objective-C
// 使用自動布局進(jìn)行初始化
NSView *firstView = [[NSView alloc] init];
NSView *secondView = [[NSView alloc] init];
[firstView setTranslatesAutoresizingMaskIntoConstraints:NO]; // 禁用自動轉(zhuǎn)換約束
[secondView setTranslatesAutoresizingMaskIntoConstraints:NO];
[firstTab setView:firstView];
[secondTab setView:secondView];
[NSLayoutConstraint activateConstraints:@[
[firstView.leadingAnchor constraintEqualToAnchor:tabView.leadingAnchor],
[firstView.trailingAnchor constraintEqualToAnchor:tabView.trailingAnchor],
[firstView.topAnchor constraintEqualToAnchor:tabView.topAnchor],
[firstView.bottomAnchor constraintEqualToAnchor:tabView.bottomAnchor],
[secondView.leadingAnchor constraintEqualToAnchor:tabView.leadingAnchor],
[secondView.trailingAnchor constraintEqualToAnchor:tabView.trailingAnchor],
[secondView.topAnchor constraintEqualToAnchor:tabView.topAnchor],
[secondView.bottomAnchor constraintEqualToAnchor:tabView.bottomAnchor]
]];
Swift
// 使用自動布局進(jìn)行初始化
let firstView = NSView()
let secondView = NSView()
firstView.translatesAutoresizingMaskIntoConstraints = false // 禁用自動轉(zhuǎn)換約束
secondView.translatesAutoresizingMaskIntoConstraints = false
firstTab.view = firstView
secondTab.view = secondView
NSLayoutConstraint.activate([
firstView.leadingAnchor.constraint(equalTo: tabView.leadingAnchor),
firstView.trailingAnchor.constraint(equalTo: tabView.trailingAnchor),
firstView.topAnchor.constraint(equalTo: tabView.topAnchor),
firstView.bottomAnchor.constraint(equalTo: tabView.bottomAnchor),
secondView.leadingAnchor.constraint(equalTo: tabView.leadingAnchor),
secondView.trailingAnchor.constraint(equalTo: tabView.trailingAnchor),
secondView.topAnchor.constraint(equalTo: tabView.topAnchor),
secondView.bottomAnchor.constraint(equalTo: tabView.bottomAnchor)
])
高級用法
動態(tài)增減標(biāo)簽頁
Objective-C
添加標(biāo)簽頁
NSTabViewItem *newTab = [[NSTabViewItem alloc] initWithIdentifier:@"newTab"];
[newTab setLabel:@"New Tab"]; // 設(shè)置新標(biāo)簽頁名稱
NSView *newView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 600, 400)];
[newView setWantsLayer:YES];
[newView.layer.backgroundColor = [NSColor greenColor].CGColor];
[newTab setView:newView];
// 動態(tài)添加到 TabView
[tabView addTabViewItem:newTab];
移除標(biāo)簽頁
NSTabViewItem *tabToRemove = [tabView tabViewItemAtIndex:0];
[tabView removeTabViewItem:tabToRemove];
Swift
添加標(biāo)簽頁
let newTab = NSTabViewItem(identifier: "newTab")
newTab.label = "New Tab" // 設(shè)置新標(biāo)簽頁名稱
let newView = NSView(frame: NSRect(x: 0, y: 0, width: 600, height: 400))
newView.wantsLayer = true
newView.layer?.backgroundColor = NSColor.green.cgColor
newTab.view = newView
// 動態(tài)添加到 TabView
tabView.addTabViewItem(newTab)
移除標(biāo)簽頁
if let tabToRemove = tabView.tabViewItem(at: 0) {
tabView.removeTabViewItem(tabToRemove)
}
自定義標(biāo)簽
你可以通過自定義視圖來替換 NSTabViewItem 的默認(rèn)標(biāo)題視圖。
Objective-C
// 自定義標(biāo)簽視圖
NSTabViewItem *customTab = [[NSTabViewItem alloc] initWithIdentifier:@"customTab"];
NSView *customLabelView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 30)];
NSTextField *customLabel = [[NSTextField alloc] initWithFrame:customLabelView.bounds];
[customLabel setStringValue:@"Custom Tab"];
[customLabel setBezeled:NO];
[customLabel setDrawsBackground:NO];
[customLabel setEditable:NO];
[customLabel setSelectable:NO];
[customLabelView addSubview:customLabel];
[customTab setLabelView:customLabelView];
// 創(chuàng)建內(nèi)容視圖
NSView *customView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 600, 400)];
[customView setWantsLayer:YES];
[customView.layer.backgroundColor = [NSColor yellowColor].CGColor];
[customTab setView:customView];
// 將自定義標(biāo)簽頁添加到 TabView
[tabView addTabViewItem:customTab];
Swift
// 自定義標(biāo)簽視圖
let customTab = NSTabViewItem(identifier: "customTab")
let customLabelView = NSView(frame: NSMakeRect(0, 0, 100, 30))
let customLabel = NSTextField(frame: customLabelView.bounds)
customLabel.stringValue = "Custom Tab"
customLabel.isBezeled = false
customLabel.drawsBackground = false
customLabel.isEditable = false
customLabel.isSelectable = false
customLabelView.addSubview(customLabel)
customTab.labelView = customLabelView
// 創(chuàng)建內(nèi)容視圖
let customView = NSView(frame: NSRect(x: 0, y: 0, width: 600, height: 400))
customView.wantsLayer = true
customView.layer?.backgroundColor = NSColor.yellow.cgColor
customTab.view = customView
// 將自定義標(biāo)簽頁添加到 TabView
tabView.addTabViewItem(customTab)
切換標(biāo)簽頁
你可以通過代碼來控制標(biāo)簽頁的切換。
Objective-C
// 選中第一個標(biāo)簽頁
[tabView selectTabViewItemAtIndex:0];
// 選中特定標(biāo)識符的標(biāo)簽頁
NSTabViewItem *tabItem = [tabView tabViewItemAtIndex:0];
[tabView selectTabViewItem:tabItem];
Swift
// 選中第一個標(biāo)簽頁
tabView.selectTabViewItem(at: 0)
// 選中特定標(biāo)識符的標(biāo)簽頁
if let tabItem = tabView.tabViewItem(at: 0) {
tabView.selectTabViewItem(tabItem)
}
刷新標(biāo)簽視圖
在某些情況下,您可能需要刷新標(biāo)簽視圖的內(nèi)容,例如在標(biāo)簽名稱發(fā)生變化時。
Objective-C
- (void)refreshTabLabel:(NSTabViewItem *)tabItem newLabel:(NSString *)newLabel {
[tabItem setLabel:newLabel];
[tabView updateTabViewItems]; // 刷新標(biāo)簽視圖
}
Swift
func refreshTabLabel(_ tabItem: NSTabViewItem, newLabel: String) {
tabItem.label = newLabel
tabView.updateTabViewItems() // 刷新標(biāo)簽視圖
}
封裝工具類
為了更方便地使用 NSTabView,可以封裝一個工具類,提供常見功能的高層接口。
Objective-C
#import <Cocoa/Cocoa.h>
@interface NSTabViewHelper : NSObject
+ (NSTabView *)createTabViewWithFrame:(NSRect)frame tabItems:(NSArray<NSDictionary<NSString *, NSView *> *> *)tabItems;
+ (void)addTabWithLabel:(NSString *)label toTabView:(NSTabView *)tabView withView:(NSView *)view;
@end
@implementation NSTabViewHelper
+ (NSTabView *)createTabViewWithFrame:(NSRect)frame tabItems:(NSArray<NSDictionary<NSString *, NSView *> *> *)tabItems {
NSTabView *tabView = [[NSTabView alloc] initWithFrame:frame];
for (NSDictionary<NSString *, NSView *> *item in tabItems) {
NSString *label = item.allKeys.firstObject;
NSView *view = item.allValues.firstObject;
[NSTabViewHelper addTabWithLabel:label toTabView:tabView withView:view];
}
return tabView;
}
+ (void)addTabWithLabel:(NSString *)label toTabView:(NSTabView *)tabView withView:(NSView *)view {
NSTabViewItem *tabItem = [[NSTabViewItem alloc] initWithIdentifier:label];
[tabItem setLabel:label];
[tabItem setView:view];
[tabView addTabViewItem:tabItem];
}
@end
Swift
import Cocoa
class NSTabViewHelper {
// 創(chuàng)建 TabView 并初始化標(biāo)簽項
static func createTabView(frame: NSRect, tabItems: [String: NSView]) -> NSTabView {
let tabView = NSTabView(frame: frame)
for (label, view) in tabItems {
addTab(withLabel: label, to: tabView, with: view)
}
return tabView
}
// 添加標(biāo)簽頁
static func addTab(withLabel label: String, to tabView: NSTabView, with view: NSView) {
let tabItem = NSTabViewItem(identifier: label)
tabItem.label = label
tabItem.view = view
tabView.addTabViewItem(tabItem)
}
}
使用示例
Objective-C
// 創(chuàng)建 TabView
NSView *firstView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 600, 400)];
[firstView setWantsLayer:YES];
[firstView.layer setBackgroundColor:[NSColor redColor].CGColor];
NSView *secondView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 600, 400)];
[secondView setWantsLayer:YES];
[secondView.layer setBackgroundColor:[NSColor blueColor].CGColor];
NSTabView *tabView = [NSTabViewHelper createTabViewWithFrame:NSMakeRect(0, 0, 600, 400)
tabItems:@[
@{@"First Tab": firstView},
@{@"Second Tab": secondView}
]];
Swift
// 創(chuàng)建 TabView
let firstView = NSView(frame: NSRect(x: 0, y: 0, width: 600, height: 400))
firstView.wantsLayer = true
firstView.layer?.backgroundColor = NSColor.red.cgColor
let secondView = NSView(frame: NSRect(x: 0, y: 0, width: 600, height: 400))
secondView.wantsLayer = true
secondView.layer?.backgroundColor = NSColor.blue.cgColor
let tabView = NSTabViewHelper.createTabView(frame: NSRect(x: 0, y: 0, width: 600, height: 400), tabItems: [
"First Tab": firstView,
"Second Tab": secondView
])
總結(jié)
通過了解 NSTabView 的基本使用、委托方法、動態(tài)增減標(biāo)簽頁、自定義標(biāo)簽等高級用法,以及封裝工具類,你將能夠更高效地使用 NSTabView 創(chuàng)建復(fù)雜的選項卡界面。在實際應(yīng)用中,合理使用這些技巧可以顯著提升用戶界面的靈活性和用戶體驗。
將來的你會感謝今天如此努力的你!
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。

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