macOS NStableView的基本操作
先睹为快。看到效果在学习,进步会更快!
点击搜索后
选中请求返回项,还可以鼠标右键显示菜单栏。
这是一个简单的搜索框 + 按钮 + 列表 + 右键菜单栏
我们来看看代码
1.#import "ViewController.h"
#import <Cocoa/Cocoa.h> @interface ViewController : NSViewController @end
2.ViewController.m
#import "ViewController.h" #import "Masonry.h"//没有导入Masonry框架的也可以使用原生布局 #import "MarketTableViewCell.h" @interface ViewController ()<NSTableViewDelegate,NSTableViewDataSource> /** macos 输入框 */ @property (nonatomic, weak) NSTextField *inputTextField; /** macos 搜索按钮 */ @property (nonatomic, weak) NSButton *btnSearch; /** 数据列表 */ @property (nonatomic, strong) NSTableView *dataTableView; /** 数据 */ @property (nonatomic, strong) NSArray *dataSource; /** 滚动显示 */ @property (nonatomic, strong) NSScrollView *scrollView; @property (nonatomic, strong) NSMenu *unBindinDviceListMenu; @end @implementation ViewController #pragma mark 懒加载 macos 输入框 - (NSTextField *)inputTextField { if (!_inputTextField) { NSTextField *lbl = [[NSTextField alloc] init]; [self.view addSubview:lbl]; _inputTextField = lbl; } return _inputTextField; } #pragma mark 懒加载 macos 按钮 - (NSButton *)btnSearch { if (!_btnSearch) { NSButton *btn = [[NSButton alloc] init]; [self.view addSubview:btn]; _btnSearch = btn; } return _btnSearch; } #pragma mark 懒加载 -(NSScrollView *)scrollView//容器视图 { if (!_scrollView) { _scrollView = [[NSScrollView alloc] init]; [_scrollView setHasVerticalScroller:YES]; [_scrollView setHasHorizontalScroller:YES]; [_scrollView setFocusRingType:NSFocusRingTypeNone]; [_scrollView setAutohidesScrollers:YES]; [_scrollView setBorderType:NSNoBorder]; [_scrollView setTranslatesAutoresizingMaskIntoConstraints:NO]; NSScrollerStyle style = [NSScroller preferredScrollerStyle]; [_scrollView setScrollerStyle:style]; [self.view addSubview:_scrollView]; } return _scrollView; } -(NSTableView *)dataTableView //数据列表 { if(!_dataTableView){ _dataTableView = [[NSTableView alloc] init]; _dataTableView.backgroundColor = [NSColor clearColor]; _dataTableView.delegate = self; _dataTableView.dataSource = self; _dataTableView.rowHeight = 24; [_dataTableView setGridColor: [NSColor yellowColor]]; [_dataTableView setGridStyleMask:NSTableViewSolidVerticalGridLineMask|NSTableViewSolidHorizontalGridLineMask]; [_dataTableView setAutoresizesSubviews:YES]; [_dataTableView setColumnAutoresizingStyle:NSTableViewNoColumnAutoresizing]; _dataTableView.usesAlternatingRowBackgroundColors = YES; [_dataTableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular]; [self.scrollView setDocumentView:self.dataTableView]; } return _dataTableView; } - (NSArray*)dataSource{ if(!_dataSource){ _dataSource = [NSArray array]; } return _dataSource; } -(void)viewDidLoad { [super viewDidLoad]; [self layoutView]; } #pragma mark - UI控件布局 -(void)layoutView{ [self.inputTextField mas_makeConstraints:^(MASConstraintMaker *make) { make.top.offset(30); make.left.offset(20); make.width.offset(300); make.height.offset(20); }]; [self.btnSearch mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.inputTextField.mas_top).offset(-2); make.left.equalTo(self.inputTextField.mas_right).offset(20); make.width.offset(60); make.height.offset(24); }]; [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.offset(180); make.left.offset(14); make.right.offset(-14); make.bottom.offset(-44); }];
//不要设置dataTableViewde 位置了,会导致scrollview无法拉伸 // [self.dataTableView mas_makeConstraints:^(MASConstraintMaker *make) { // make.top.offset(0); // make.left.offset(0); // make.width.offset(0); // make.height.offset(0); //}]; //macOS NSTextField的属性按需要选择使用 self.inputTextField.editable = YES;//设置是否可以编辑 self.inputTextField.bordered = NO; //不显示边框 self.inputTextField.backgroundColor = [NSColor clearColor]; //控件背景色 self.inputTextField.textColor = [NSColor whiteColor]; //文字颜色 self.inputTextField.alignment = NSTextAlignmentLeft; //水平显示方式 self.inputTextField.maximumNumberOfLines = 2; //最多显示行数 self.inputTextField.stringValue = @"13760106236"; //现实的文字内容 self.inputTextField.font = [NSFont systemFontOfSize:14];//设置字号大小 // 1. 按钮文字 self.btnSearch.title = @"搜索"; // 2. 按钮触发的方法 [self.btnSearch setTarget:self]; [self.btnSearch setAction:@selector(btnSearchClick)]; //设置NSTableView头部标签 NSArray *temp = @[@"shouji",@"province",@"city",@"company",@"cardtype",@"areacode"]; NSArray *columns = [self TradeColumnsOfIdentifiers:temp]; for(NSTableColumn *column in columns){ NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; [style setAlignment:NSTextAlignmentLeft]; column.headerCell.attributedStringValue = [[NSAttributedString alloc] initWithString:column.headerCell.attributedStringValue.string attributes:@{NSForegroundColorAttributeName:[NSColor whiteColor], NSParagraphStyleAttributeName:style}]; column.width = 120; [self.dataTableView addTableColumn:column]; } } #pragma mark NSTableView头部标签 -(NSArray*)TradeColumnsOfIdentifiers:(NSArray*)identiferArray{ if(identiferArray.count<=0)return nil; NSMutableArray *columns = @[].mutableCopy; for(NSString *indentifier in identiferArray){ NSTableColumn *column = [self columnWithIndentifier:indentifier]; [columns addObject:column]; } return columns; } -(NSTableColumn*)columnWithIndentifier:(NSString*)indentifier{ return [self columnWithIndentifier:indentifier singleColor:NO]; } -(NSTableColumn*)columnWithIndentifier:(NSString*)indentifier singleColor:(BOOL)singleColor{ NSTableHeaderCell *cell = [[NSTableHeaderCell alloc] init]; NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:indentifier]; if(!singleColor) column.headerCell = cell; NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; NSString *title = nil; if([indentifier isEqualToString:@"shouji"]){ title = @"手机号"; [column.headerCell setAlignment:NSTextAlignmentCenter]; }else if([indentifier isEqualToString:@"province"]){ title = @"省份"; [column.headerCell setAlignment:NSTextAlignmentCenter]; }else if([indentifier isEqualToString:@"city"]){ title = @"城市"; [column.headerCell setAlignment:NSTextAlignmentCenter]; }else if([indentifier isEqualToString:@"company"]){ title = @"运营商"; [column.headerCell setAlignment:NSTextAlignmentCenter]; }else if([indentifier isEqualToString:@"cardtype"]){ title = @"卡类型"; [column.headerCell setAlignment:NSTextAlignmentCenter]; }else if([indentifier isEqualToString:@"areacode"]){ title = @"卡编码"; [column.headerCell setAlignment:NSTextAlignmentCenter]; }else{ title = @"--"; } column.identifier = indentifier; [style setAlignment:column.headerCell.alignment]; column.headerCell.attributedStringValue = [[NSAttributedString alloc] initWithString:title attributes:@{NSForegroundColorAttributeName:[NSColor redColor], NSParagraphStyleAttributeName:style}]; return column; } #pragma mark 按钮触发事件 - (void)btnSearchClick{ // 处理点击事件 NSLog(@"点击了搜索"); // 获取输入框输入数据 if (self.inputTextField.stringValue.length == 0 || [self.inputTextField.stringValue isEqualToString:@""]) { [self tips:@"请输入要查询的手机号"]; }else{ [self postRequest:self.inputTextField.stringValue]; } } #pragma mark - 提示框 - (void)tips:(NSString *)tipsString{ NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = @"提示"; alert.informativeText = tipsString;//内容 [alert addButtonWithTitle:@"确定"];//按钮所显示的文案 [alert runModal]; } #pragma mark - NSURLSession - post请求 - (void)postRequest:(NSString *)inputString{ //1.创建url NSURL *url = [NSURL URLWithString:@"https://api.jisuapi.com/shouji/query?"]; //2.创建请求 NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url]; //2.5核心设置body mutableRequest.HTTPMethod = @"POST";//或者[mutableRequest setHTTPMethod:@"POST"];请求方法 NSString *structureRequest = [NSString stringWithFormat:@"appkey=d52273a85bbe39fd&shouji=%@",inputString];//拼接请求参数 mutableRequest.HTTPBody = [structureRequest dataUsingEncoding:NSUTF8StringEncoding];//UTF8解码 //3.创建session对象 NSURLSession *session = [NSURLSession sharedSession]; //4.创建task对象 NSURLSessionDataTask *task = [session dataTaskWithRequest:mutableRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { //5.解析 if (error == nil) { NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; NSLog(@"dic = %@", dic); if ([dic[@"msg"] isEqualToString:@"ok"]) { // 3.GCD dispatch_async(dispatch_get_main_queue(), ^{ // UI更新代码 NSMutableArray *arr = [NSMutableArray array]; [arr addObject:dic[@"result"]];//字典装数组 self.dataSource = arr; [self.dataTableView reloadData];//刷新NSTableview }); } } }]; //6.启动任务 [task resume]; } // 行数 - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { return self.dataSource.count; } #pragma mark - TableView Delegate - (NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{ NSDictionary *data = self.dataSource[row]; NSString *identifier = tableColumn.identifier; NSView *view = [tableView makeViewWithIdentifier:identifier owner:self]; MarketTableViewCell *cellView; if (!view) { cellView = [[MarketTableViewCell alloc] init]; cellView.identifier = identifier; view = cellView; }else{ cellView = (MarketTableViewCell*)view; } cellView.textField.alignment = NSTextAlignmentRight; NSString * strValue = [self GetListtableColumnValue:tableColumn NapshotData:data cellView:cellView]; cellView.textField.stringValue = strValue ?: @"--"; return cellView; } //没有需要就不用它,这会导致刷新失败涉及页面多以后 //- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row //{ // if(row== NSNotFound||row==-1||row>=self.dataSource.count||self.dataSource.count<=0)return NO; // if([tableView isEqualTo:self.dataTableView]){ //self.dataTableView = self.dataSource[row];////支持单选而已,把数据存起来 // } //return YES; //} #pragma mark -tableviewCell 赋值 -(NSString *)GetListtableColumnValue:(NSTableColumn *)tableColumn NapshotData:(NSDictionary *)shotData cellView:(MarketTableViewCell*)cellView{ NSString *Value = @""; if([tableColumn.identifier isEqualToString:@"shouji"]){ //手机 cellView.textField.alignment = NSTextAlignmentCenter; Value = shotData[@"shouji"]; }else if([tableColumn.identifier isEqualToString:@"province"]) { //省份 cellView.textField.alignment = NSTextAlignmentCenter; Value = shotData[@"province"]; }else if([tableColumn.identifier isEqualToString:@"city"]) { //城市 cellView.textField.alignment = NSTextAlignmentCenter; Value = shotData[@"city"]; }else if([tableColumn.identifier isEqualToString:@"company"]) { //运营商 cellView.textField.alignment = NSTextAlignmentCenter; Value = shotData[@"company"]; }else if([tableColumn.identifier isEqualToString:@"cardtype"]) { //卡类型 cellView.textField.alignment = NSTextAlignmentCenter; Value = shotData[@"cardtype"]; }else if([tableColumn.identifier isEqualToString:@"areacode"]) { //卡编号 cellView.textField.alignment = NSTextAlignmentCenter; Value = shotData[@"areacode"]; }else{ } return Value; } #pragma mark - 鼠标事件 - (void)rightMouseDown:(NSEvent *)event{ //创建Menu NSMenu *theMenu = [[NSMenu alloc] initWithTitle:@"Contextual Menu"]; //常规添加菜单 [theMenu insertItemWithTitle:@"Item 1"action:@selector(beep:)keyEquivalent:@""atIndex:0]; [theMenu insertItemWithTitle:@"Item 2"action:@selector(beep:)keyEquivalent:@""atIndex:1]; //自定义的NSMenuItem NSMenuItem *item3 = [[NSMenuItem alloc]init]; item3.title = @"Item 38"; item3.target = self; item3.action = @selector(beep:); [theMenu insertItem:item3 atIndex:2]; [NSMenu popUpContextMenu:theMenu withEvent:event forView:self.view]; } #pragma mark 统一使用响应方法,不然不使用该方法的菜单栏将不能点击 -(void)beep:(NSMenuItem *)menuItem{ NSLog(@"_____%@", menuItem); } @end
3.MarketTableViewCell.h
#import <Cocoa/Cocoa.h> #import <Quartz/Quartz.h> @interface MarketTableViewCell : NSView @property (nonatomic, strong)NSTextField *textField; @end
4.MarketTableViewCell.m
#import "MarketTableViewCell.h" #import "Masonry.h" @implementation MarketTableViewCell - (NSTextField*)textField{ if(!_textField){ _textField = [[NSTextField alloc] init]; [_textField setBezeled:NO]; [_textField setAlignment:NSTextAlignmentCenter]; _textField.font = [NSFont labelFontOfSize:13.0]; _textField.textColor = [NSColor redColor]; [self addSubview:self.textField]; } return _textField; } - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; } - (instancetype)initWithFrame:(NSRect)frameRect{ self = [super initWithFrame:frameRect]; if(self){ self.wantsLayer = YES; [self layoutSubViews];//UI布局 } return self; } - (void)layoutSubViews{ [self.textField mas_makeConstraints:^(MASConstraintMaker *make) { make.left.offset(1); make.right.offset(-1); (void)make.centerY; }]; }
#pragma mark - 事件
- (void)tableViewDoubleAction:(NSTableView*)tableView{
NSInteger index=tableView.clickedRow;
if(index==NSNotFound||index<0||index>=self.dataSource.count)
return ;
[self tableViewDoubleActionAtRow:index];
}
- (void)tableViewDoubleActionAtRow:(NSInteger)row{
DLog(@"在%ld行双击", row);
}
/*!
改变选中项
*/
// 鼠标选中tableView,获取选中行
- (void)tableViewSelectionDidChange:(NSNotification *)notification{//
NSTableView *tableView = (NSTableView*)notification.object;
NSInteger selectedRow = tableView.selectedRow;
DLog(@"当前选择了第%ld行。",selectedRow);
NSInteger row = [self.tableView selectedRow];
if(row>self.dataSource.count||row==NSNotFound||row<0)
return;
[self tableViewSelectionDidChangeAtRow:row];
}
- (void)tableViewSelectionDidChangeAtRow:(NSInteger)row{
DLog(@"选中改变到%ld行", row);
}
@end