macOS开发-NSTableView

1,713 阅读2分钟

NSTableView

1.简介

​ 一组相关记录,显示在代表单个记录的行和代表这些记录的属性的列中。

参考

官方文档

@interface NSTableView : NSControl <NSUserInterfaceValidations, NSTextViewDelegate, NSDraggingSource, NSAccessibilityTable>

2.代码实现

1.1 基础创建

//
//  ViewController.m
//  ZDMacOSDemo
//
//  Created by forget on 2020/10/19.
//

#import "ViewController.h"

@interface ViewController ()<NSTableViewDelegate, NSTableViewDataSource>// 系统
  
- (instancetype)initWithFrame:(NSRect)frameRect NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

@property (nullable, weak) id <NSTableViewDataSource> dataSource;
@property (nullable, weak) id <NSTableViewDelegate> delegate;

#import "ViewController.h"

@interface ViewController ()<NSTableViewDelegate, NSTableViewDataSource>
// 创建TableView
NSTableView *tableView = [[NSTableView alloc] initWithFrame:CGRectMake(0, 0, 1000, 500)];
// 隐藏header
tableView.headerView = nil; 
tableView.dataSource = self;
tableView.delegate = self;
tableView.backgroundColor = NSColor.blueColor;
[self.view addSubview:tableView];

此时运行并不显示在界面上,即使你设置了背景色,因为此时NSTableView的column=0。

storyboard创建的 column != 0,直接拖拽的 NSTableView会生成一个 column 默认值。

1.2 添加可滑动区域

创建NSScrollView并将上面创建的NSTableView添加到ScrollView上

NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:CGRectMake(10, 10, 150, 500)];
scrollView.hasVerticalScroller = YES;
// scrollView.autohidesScrollers = YES;
// scrollView.backgroundColor = NSColor.redColor;
[self.view addSubview:scrollView];
scrollView.contentView.documentView = tableView;

1.3 添加 cloumn

// 创建Column并添加到tableView,可添加多个
NSTableColumn *column1 = [[NSTableColumn alloc] initWithIdentifier:@"nameID"];
column1.width = scrollView.frame.size.width;
column1.title = @"name";
[tableView addTableColumn:column1];

1.4 常用代理方法

// 行数
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
    return self.dataSource.count;
}
// 绑定数据源
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    return self.dataSource[row];
}
// 行高度
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
    return 30;
}
// 点击行cell的通知
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
    NSTableView *tableView = notification.object;
}
// 点击column,多用于排序等
- (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn {
    
}
// 鼠标点击Column,效果同上didClickTableColumn
- (void)tableView:(NSTableView *)tableView mouseDownInHeaderOfTableColumn:(NSTableColumn *)tableColumn {
    
}
// cell将会出现,可用于修改样式
- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    NSTextFieldCell *tfCell = (NSTextFieldCell *)cell;
    tfCell.textColor = NSColor.redColor;
    tfCell.font = [NSFont systemFontOfSize:18];
    tfCell.selectable = NO;
    tfCell.editable = NO;
    tfCell.alignment = NSTextAlignmentCenter;
}
// 鼠标悬浮在cell上的提示内容
- (NSString *)tableView:(NSTableView *)tableView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation {
    return self.dataSource[row];
}

1.5 其他业务需求

  • 拖拽

    一些文件管理器等都需要支持拖拽功能

    - (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
      // 必须注册拖拽类型,也可以在创建table的时候注册
        [tableView registerForDraggedTypes:@[@"dataType"]];
        NSData *setData = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes requiringSecureCoding:NO error:nil];
        [pboard declareTypes:@[@"dataType"] owner:self];
        [pboard setData:setData forType:@"dataType"];
        return YES;
    }
    
    - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id<NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation {
        return NSDragOperationEvery;
    }
    
    - (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info
              row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation {
        NSPasteboard* pboard = [info draggingPasteboard];
        NSData* rowData = [pboard dataForType:@"dataType"];
        NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSIndexSet class] fromData:rowData error:nil];
        NSInteger dragRow = [rowIndexes firstIndex];
        
        if (dragRow < row) {
            [self.dataSource insertObject:[self.dataSource objectAtIndex:dragRow] atIndex:row];
            [self.dataSource removeObjectAtIndex:dragRow];
            [self.tableView noteNumberOfRowsChanged];
            [self.tableView reloadData];
            
            return YES;
            
        } // end if
        
        NSString *zData = [self.dataSource objectAtIndex:dragRow];
        [self.dataSource removeObjectAtIndex:dragRow];
        [self.dataSource insertObject:zData atIndex:row];
        [self.tableView noteNumberOfRowsChanged];
        [self.tableView reloadData];
        
        return YES;
    }
    
  • 双击tableView

    [tableView setDoubleAction:@selector(tableViewDoubleClick:)];
    // 实现双击方法
    - (void)tableViewDoubleClick:(NSTableView *)sender {
        if (sender.selectedRow > -1) {
            ZDDoc *doc = self.dataSource[sender.selectedRow];
            NSLog(@"%@", doc);
        }
    }
    
  • 点击cloumn排序

    一个cloumn只能添加一个排序属性

    // 1.添加排序属性
    @interface ZDDoc : NSObject
    @property (strong, nonatomic) NSString *name;
    @property (assign, nonatomic) NSInteger index;// 进行排序的属性
    @end
    // 2.cloumn添加sortDescriptorPrototype
    column1.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:@"index" ascending:NO];
    // 3.实现sortDescriptorsDidChange
    - (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray<NSSortDescriptor *> *)oldDescriptors {
        [self.dataSource sortUsingDescriptors:tableView.sortDescriptors];
    }
    

3.xib实现