企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# NSTabView [TOC] *** # 一、xib 简单创建 NSTabView ![tabView](/Users/MelissaShu/macos/tabView.png) *** ## 1、拖拽控件到 xib 在 xib 右下侧控件栏,搜索 tabView,拖拽到 xib面板上,就创建了一个tabView。 tabView 自带两个 NSTabViewItem,就是上方的两个按键; 从控件工具箱拖拽 NSButton、NSImageView 到 tabview 面板上;点击上方 NSTabViewItem,即可切换面板,再次拖拽控件到面板。运行,就可以看到效果。 可以修改右侧的style 属性,来修改 NSTabViewItem 的位置,和边框的样式。对应到代码中的属性为 tabPosition 和 tabViewBorderType。 *** ## 2、使用 NSViewController 控制 tabview 的内容显示。 2.1 这里我没有用xib 和 storyboard。我将tabview 连线到xib关联的 controller. ![tabview-xib](/Users/MelissaShu/macos/tabview-xib.png) 2.2 创建两个类 SecViewController、ThirdViewController 继承自 NSViewController,并添加控件到 ViewControlle 的 xib上。 2.3 获取到 tabview 的所有 items,并设置 item.view 为上面两个类的view ``` SecViewController *secVC = [[SecViewController alloc]init]; ThirdViewController *thirdVC = [[ThirdViewController alloc]init]; NSArray *tabItems = self.tabView.tabViewItems; NSTabViewItem *item0 = tabItems[0]; // [item0.view addSubview:secVC.view]; //无效 [item0 setView:secVC.view]; //注意尺寸,如果在 secVC 的内容超过了 tabView 的尺寸,可能超出的内容不会显示 NSTabViewItem *item1 = tabItems[1]; [item1 setView:thirdVC.view]; ``` 再次运行就可以看到 tabview 显示的内容分别为 SecViewController、ThirdViewController 的view。 如果你看不到上面类的内容,可能是拖拽控件的位置,超过了 tabview.frame。 *** # 二、纯代码创建 NSTabView ## 1、初始化 tabview ``` NSTabView *tabView = [[NSTabView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)]; //如果尺寸较小,而item长度容纳不下,会被挤出去 //默认是透明色 tabView.delegate = self; tabView.tabPosition = NSTabPositionLeft; //显示位置:显示在左侧 tabView.tabViewBorderType = NSTabViewBorderTypeBezel;//边框样式:bezel类型边框 [self.view addSubview:tabView]; ``` 其中 tabPosition 和 tabViewBorderType 的值对应下面枚举 ### NSTabPosition ``` typedef NS_ENUM(NSUInteger, NSTabPosition) { NSTabPositionNone = 0,//无 NSTabPositionTop = 1,//上 NSTabPositionLeft = 2,//左 NSTabPositionBottom = 3,//下 NSTabPositionRight = 4//右 } NS_AVAILABLE_MAC(10_12); ``` ------ ### NSTabViewBorderType ``` typedef NS_ENUM(NSUInteger, NSTabViewBorderType) { NSTabViewBorderTypeNone = 0, NSTabViewBorderTypeLine = 1, NSTabViewBorderTypeBezel = 2 } NS_AVAILABLE_MAC(10_12); ``` *** ### NSTabViewType 过期 使用 tabPosition 和 tabViewBorderType 代替 ``` typedef NS_ENUM(NSUInteger, NSTabViewType) { NSTopTabsBezelBorder = 0, // the default NSLeftTabsBezelBorder = 1, NSBottomTabsBezelBorder = 2, NSRightTabsBezelBorder = 3, NSNoTabsBezelBorder = 4, NSNoTabsLineBorder = 5, NSNoTabsNoBorder = 6 }; ``` *** ## 2、创建item 可以使用 init 方法创建,再去设置view; 也可以使用 tabViewItemWithViewController 来创建item,并添加 ``` SecViewController *secVC = [[SecViewController alloc]init]; ThirdViewController *thirdVC = [[ThirdViewController alloc]init]; NSTabViewItem *item0 = [[NSTabViewItem alloc]init]; [item0 setView:secVC.view]; NSTabViewItem *item1 = [[NSTabViewItem alloc]init]; NSTabViewItem *item2 = [[NSTabViewItem alloc]init]; // NSTabViewItem *item3 = [[NSTabViewItem alloc]init]; NSTabViewItem *item3 = [NSTabViewItem tabViewItemWithViewController:thirdVC]; item0.label = @"item0"; item1.label = @"item1"; item2.label = @"item2"; item3.label = @"item3"; ``` NSTabViewItem 继承自 NSObject ### 2.1 初始化方法 ``` + (instancetype)tabViewItemWithViewController:(NSViewController *)viewController NS_AVAILABLE_MAC(10_10); - (instancetype)initWithIdentifier:(nullable id)identifier; ``` *** ### 2.2 常用属性 ``` @property (strong, nullable) id identifier; @property (copy) NSString *label; @property (nullable, strong) NSView *view; @property (nullable, strong) NSViewController *viewController @property (nullable, readonly) NSTabView *tabView; @property (readonly) NSTabState tabState; @property (nullable, weak) NSView *initialFirstResponder; ``` 添加item(第三步) 后写下如下代码: ``` NSLog(@"\n tabView : %@ \n viewController : %@ \n view : %@ \n thirdVC : %@ \n thirdVC.view : %@ \n initialFirstResponder : %@ ",item3.tabState,item3.tabView,item3.viewController,item3.view,thirdVC,thirdVC.view,item3.initialFirstResponder); ``` 打印日志如下: ``` tabView : <NSTabView: 0x100529f30> viewController : <ThirdViewController: 0x6000000c9450> view : <NSView: 0x6040001223a0> thirdVC : <ThirdViewController: 0x6000000c9450> thirdVC.view : <NSView: 0x6040001223a0> initialFirstResponder : (null) ``` 可见使用 tabViewItemWithViewController 初始化的item item3.viewController = thirdVC item3.view = thirdVC.view *** 下面几个属性没用 ``` @property (copy) NSColor *color; //过期没用了 @property (nullable, strong) NSImage *image NS_AVAILABLE_MAC(10_10);//有bug 设不上 @property (nullable, copy) NSString *toolTip NS_AVAILABLE_MAC(10_6);//悬停时的提示语 ``` *** ## 3 添加 item ``` [tabView addTabViewItem:item0]; [tabView addTabViewItem:item1]; ``` 你可以使用上述方法添加item,但item多的时候,非常冗余。但又没有添加多个的方法。 这时我们可以写一个 NSTabView 的category 来添加多个 item,category 是对现有类方法的扩展。 ### 使用category 添加 item 新建 macOS -- Object-C File,填写你的名称,下面选择 Category -- NSTabView,next 即可。 ![tabview-category](/Users/MelissaShu/macos/tabview-category.png) 在 .h 和 .m 中写下如下代码 ``` #import <Cocoa/Cocoa.h> @interface NSTabView (pms) - (void)addItemFromArray:(NSArray *)itemArray; @end ``` ``` #import "NSTabView+pms.h" @implementation NSTabView (pms) - (void)addItemFromArray:(NSArray *)itemArray{ for (NSTabViewItem *item in itemArray) { [self addTabViewItem:item]; } } @end ``` 回到添加tabview 的控制器,使用下述代码添加完成所有item。 ``` [tabView addItemFromArray:@[item0,item1,item2,item3]]; ``` *** # 数据源方法 ``` //返回行数 -(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{ return 15; } -(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{ //获取表格列的标识符 NSString *columnID = tableColumn.identifier; NSLog(@"columnID : %@ ,row : %d",columnID,row); NSString *strIdt = @"123"; NSTableCellView *cell = [tableView makeViewWithIdentifier:strIdt owner:self]; if (!cell) { cell = [[NSTableCellView alloc]init]; cell.identifier = strIdt; } cell.wantsLayer = YES; cell.layer.backgroundColor = [NSColor yellowColor].CGColor; cell.imageView.image = [NSImage imageNamed:@"swift"]; cell.textField.stringValue = [NSString stringWithFormat:@"cell %ld",(long)row]; return cell; } ``` # 代理方法 NSTabViewDelegate 记得设置 `tabView.delegate = self;` ,然后在该类申明后添加 NSTabViewDelegate。 ``` @interface FirstViewController ()<NSTabViewDelegate> ``` *** 代理方法 ``` #pragma mark - NSTabViewDelegate //是否点击 - (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem{ NSLog(@"shouldSelectTabViewItem : %@ -- ",tabViewItem.label); return YES; } //即将点击item - (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem{ NSLog(@"willSelectTabViewItem : %@ -- ",tabViewItem.label); } //已点击item - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem{ NSLog(@"didSelectTabViewItem : %@ -- ",tabViewItem.label); } //item数量变化(我还没用到) - (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)tabView{ NSLog(@"tabViewDidChangeNumberOfTabViewItems --- "); } ``` *** # 优质第三方推荐 - SFTabView:https://github.com/shinyfrog/SFTabView ![SFTabView](/Users/MelissaShu/macos/SFTabView.png) *** # 参考资料 - [天狐](http://www.skyfox.org/author/admin):[Cocoa开发之NSTabView](http://www.skyfox.org/cocoa-nstabview.html) http://www.skyfox.org/cocoa-nstabview.html