macOS NStableView的基本操作


先睹为快。看到效果在学习,进步会更快!

点击搜索后

选中请求返回项,还可以鼠标右键显示菜单栏。

这是一个简单的搜索框 + 按钮 + 列表 + 右键菜单栏

我们来看看代码

1.#import "ViewController.h"

#import 

@interface ViewController : NSViewController


@end

2.ViewController.m

#import "ViewController.h"
#import "Masonry.h"//没有导入Masonry框架的也可以使用原生布局
#import "MarketTableViewCell.h"

@interface ViewController ()
/** 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);
    }];
    
    [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 
#import 

@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;
    }];

}

@end

相关