macOS开发之NSTableView的应用详解(二)

简介: macOS开发之NSTableView的应用详解

五、View-Base:基于View的TableView视图


   基于View-Base的TableView要比基于Cell的TableView更加灵活,其中每行数据载体可以是任意NSView的子类。代码示例如下:


//

//  ViewController.m

//  TableView

//

//  Created by jaki on 17/4/14.

//  Copyright © 2017年 jaki. All rights reserved.

//


#import "ViewController.h"

#import "MyCell.h"

#import "TableRow.h"

@interface ViewController()<NSTableViewDelegate,NSTableViewDataSource>


@end


@implementation ViewController

{

   NSTableView * _tableView;

   NSMutableArray * _dataArray;

}

- (void)viewDidLoad {

   [super viewDidLoad];

   _dataArray = [NSMutableArray array];

   for (int i=0; i<20; i++) {

       [_dataArray addObject:[NSString stringWithFormat:@"%d行数据",i]];

   }

   NSScrollView * scrollView    = [[NSScrollView alloc] init];

   scrollView.hasVerticalScroller  = YES;

   scrollView.frame = self.view.bounds;

   [self.view addSubview:scrollView];

   _tableView = [[NSTableView alloc]initWithFrame:self.view.bounds];

   NSTableColumn * column = [[NSTableColumn alloc]initWithIdentifier:@"test"];

   NSTableColumn * column2 = [[NSTableColumn alloc]initWithIdentifier:@"test2"];

   column2.width = 100;

   column2.minWidth = 100;

   column2.maxWidth = 100;

   column2.title = @"数据";

   column2.editable = YES ;

   column2.headerToolTip = @"提示";

   column2.hidden=NO;

   column2.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:NO];

   column.resizingMask =NSTableColumnUserResizingMask;

   _tableView.delegate = self;

   _tableView.dataSource = self;

   [_tableView addTableColumn:column];

   [_tableView addTableColumn:column2];

   scrollView.contentView.documentView = _tableView;

}


//设置行数 通用

-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{

   return _dataArray.count;

}

//View-base

//设置某个元素的具体视图

- (nullable NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row{

   //根据ID取视图

   NSTextField * view = [tableView makeViewWithIdentifier:@"cellId" owner:self];

   if (view==nil) {

       view = [[NSTextField alloc]initWithFrame:CGRectMake(0, 0, 100, 30)];

       view.backgroundColor = [NSColor clearColor];

       view.identifier = @"cellId";

   }

   return view;

}

//设置每行容器视图

- (nullable NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row{

   TableRow * rowView = [[TableRow alloc]init];

   return rowView;

}

//当添加行时调用的回调

- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row{

   NSLog(@"add");

}

//当移除行时调用的回调

- (void)tableView:(NSTableView *)tableView didRemoveRowView:(NSTableRowView *)rowView forRow:(NSInteger)row{

   NSLog(@"remove");

}

@end

上面代码中用到了TableRow类,其实它是一个自定义的继承自NSTableRowView的类,实现如下:


#import "TablerRow.h"

@implementation TablerRow

//绘制选中状态的背景

-(void)drawSelectionInRect:(NSRect)dirtyRect{

   NSRect selectionRect = NSInsetRect(self.bounds, 5.5, 5.5);

   [[NSColor colorWithCalibratedWhite:.72 alpha:1.0] setStroke];

   [[NSColor colorWithCalibratedWhite:.82 alpha:1.0] setFill];

   NSBezierPath *selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:10 yRadius:10];

   [selectionPath fill];

   [selectionPath stroke];

}

//绘制背景

-(void)drawBackgroundInRect:(NSRect)dirtyRect{

   [super drawBackgroundInRect:dirtyRect];

   [[NSColor greenColor]setFill];

   NSRectFill(dirtyRect);

}

@end

关于NSTableRowView类我们下面来做具体介绍。


六、NSTableRowView解析


   NSTableRowView用在View-Base的TableView中,其作为行容器存在。


//选中的高亮风格

/*

typedef NS_ENUM(NSInteger, NSTableViewSelectionHighlightStyle) {

   //无高亮风格

   NSTableViewSelectionHighlightStyleNone,

   //规则的高亮风格

   NSTableViewSelectionHighlightStyleRegular = 0,

   //源列表风格

   NSTableViewSelectionHighlightStyleSourceList = 1,

};

*/

@property NSTableViewSelectionHighlightStyle selectionHighlightStyle;

//是否强调

@property(getter=isEmphasized) BOOL emphasized;

//设置是否行组风格

@property(getter=isGroupRowStyle) BOOL groupRowStyle;

//是否选中状态

@property(getter=isSelected) BOOL selected;

//其前一行的选中状态

@property(getter=isPreviousRowSelected) BOOL previousRowSelected;

//其后一行的选中状态

@property(getter=isNextRowSelected) BOOL nextRowSelected;

//设置此行是否浮动

@property(getter=isFloating) BOOL floating;

//拖放拖动效果

@property(getter=isTargetForDropOperation) BOOL targetForDropOperation;

//拖放风格

@property NSTableViewDraggingDestinationFeedbackStyle draggingDestinationFeedbackStyle;

//设置拖放目标的缩进量

@property CGFloat indentationForDropOperation;

//背景色

@property(copy) NSColor *backgroundColor;


//子类重写下面方法来进行行容器视图的自定义

//画背景色

- (void)drawBackgroundInRect:(NSRect)dirtyRect;

//画选中背景

- (void)drawSelectionInRect:(NSRect)dirtyRect;

//画分割线

- (void)drawSeparatorInRect:(NSRect)dirtyRect;

//绘制拖放时的用户反馈IU

- (void)drawDraggingDestinationFeedbackInRect:(NSRect)dirtyRect;


//列数

@property(readonly) NSInteger numberOfColumns;

//提供的访问特定视图的方法

- (nullable id)viewAtColumn:(NSInteger)column;

七、来总结下NSTableViewDataSource协议


/*

无论基于Cell还是基于View,这个方法都需要实现,用来设置列表的行数

*/

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView;

/*

如果使用cell-base的TableView视图,这个方法是必须实现的,其为要渲染的cell提供数据

*/

- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;

/*

这个函数当用户编辑了cell中的内容时会被调用,一般需要在其中进行数据源的修改

*/

- (void)tableView:(NSTableView *)tableView setObjectValue:(nullable id)object forTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;

/*

当用户修改了行排序规则时调用的回调

*/

- (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray<NSSortDescriptor *> *)oldDescriptors;


//下面这些方法全部与列表的数据拖拽相关

- (nullable id <NSPasteboardWriting>)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row;

- (void)tableView:(NSTableView *)tableView draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint forRowIndexes:(NSIndexSet *)rowIndexes NS_AVAILABLE_MAC(10_7);

- (void)tableView:(NSTableView *)tableView draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation NS_AVAILABLE_MAC(10_7);

- (void)tableView:(NSTableView *)tableView updateDraggingItemsForDrag:(id <NSDraggingInfo>)draggingInfo NS_AVAILABLE_MAC(10_7);

- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard;

- (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation;

- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation;

- (NSArray<NSString *> *)tableView:(NSTableView *)tableView namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination forDraggedRowsWithIndexes:(NSIndexSet *)indexSet;

八、来总结下NSTableViewDelegate协议


//view-base的TableView相关delegate方法

/*

设置每个数据载体的View

*/

- (nullable NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;

/*

自定义行视图

*/

- (nullable NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row NS_AVAILABLE_MAC(10_7);

/*

添加一行时会调用的回调

*/

- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row;

/*

移除一行时会调用的回调

*/

- (void)tableView:(NSTableView *)tableView didRemoveRowView:(NSTableRowView *)rowView forRow:(NSInteger)row;


//cell-base的TableView相关delegate方法

/*

cell将要渲染时调用的回调,可以在其中对cell进行定制

*/

- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;

/*

设置某个cell是否可以编辑

*/

- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;

/*

设置当鼠标悬停在cell上时 显示的提示文案

*/

- (NSString *)tableView:(NSTableView *)tableView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation;

/*

当cell的宽度不够显示完全cell的内容时,设置是否允许鼠标放置扩展cell

*/

- (BOOL)tableView:(NSTableView *)tableView shouldShowCellExpansionForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;

/*

设置是否加强cell的交互能力,这样一些按钮状态的修改也会触发cell编辑的状态

*/

- (BOOL)tableView:(NSTableView *)tableView shouldTrackCell:(NSCell *)cell forTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;

/*

设置自定义cell

*/

- (nullable NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row;


//通用的TableView代理方法

/*

设置是否允许修改选中

*/

- (BOOL)selectionShouldChangeInTableView:(NSTableView *)tableView;

/*

设置某行是否可以选中

*/

- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row;

/*

当用户通过键盘或鼠标将要选中某行时,返回设置要选中的行

如果实现了这个方法,上面一个方法将不会被调用

*/

- (NSIndexSet *)tableView:(NSTableView *)tableView selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes;

/*

设置某列是否可以被选中

*/

- (BOOL)tableView:(NSTableView *)tableView shouldSelectTableColumn:(nullable NSTableColumn *)tableColumn;

/*

用户点击列头时调用的方法

*/

- (void)tableView:(NSTableView *)tableView mouseDownInHeaderOfTableColumn:(NSTableColumn *)tableColumn;

/*

用法同上

*/

- (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn;

/*

对列进行拖拽改变顺序时调用的方法

*/

- (void)tableView:(NSTableView *)tableView didDragTableColumn:(NSTableColumn *)tableColumn;

/*

设置行高

*/

- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row;

/*

下面这些方法与行检索有关

*/

- (nullable NSString *)tableView:(NSTableView *)tableView typeSelectStringForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row NS_AVAILABLE_MAC(10_5);

- (NSInteger)tableView:(NSTableView *)tableView nextTypeSelectMatchFromRow:(NSInteger)startRow toRow:(NSInteger)endRow forString:(NSString *)searchString NS_AVAILABLE_MAC(10_5);

- (BOOL)tableView:(NSTableView *)tableView shouldTypeSelectForEvent:(NSEvent *)event withCurrentSearchString:(nullable NSString *)searchString NS_AVAILABLE_MAC(10_5);

/*

设置某行是否绘制成组样式

*/

- (BOOL)tableView:(NSTableView *)tableView isGroupRow:(NSInteger)row;

/*

调整列宽度

*/

- (CGFloat)tableView:(NSTableView *)tableView sizeToFitWidthOfColumn:(NSInteger)column;

/*

设置是否支持列的移动排序

*/

- (BOOL)tableView:(NSTableView *)tableView shouldReorderColumn:(NSInteger)columnIndex toColumn:(NSInteger)newColumnIndex;

//设置某行向左或向右滑动时要显示的功能按钮

/*

typedef NS_ENUM(NSInteger, NSTableRowActionEdge) {

   NSTableRowActionEdgeLeading, // 左划

   NSTableRowActionEdgeTrailing, // 右划

} NS_ENUM_AVAILABLE_MAC(10_11);

*/

- (NSArray<NSTableViewRowAction *> *)tableView:(NSTableView *)tableView rowActionsForRow:(NSInteger)row edge:(NSTableRowActionEdge)edge NS_AVAILABLE_MAC(10_11);

/*

TableView选中修改时调用

*/

- (void)tableViewSelectionDidChange:(NSNotification *)notification;

/*

TableView列移动完成时调用的函数

*/

- (void)tableViewColumnDidMove:(NSNotification *)notification;

/*

TableView列宽度变化时调用的函数

*/

- (void)tableViewColumnDidResize:(NSNotification *)notification;

/*

TableView选中正在修改时调用的函数

*/

- (void)tableViewSelectionIsChanging:(NSNotification *)notification;


 

目录
相关文章
|
3月前
|
安全 前端开发 iOS开发
揭秘 electron-builder:macOS 应用打包背后到底发生了什么?
本文详细介绍了 Electron 应用在 macOS 平台上的打包流程,涵盖配置文件、打包步骤、签名及 notarization 等关键环节。通过剖析 `electron-builder` 的源码,展示了如何处理多架构应用、执行签名,并解决常见问题。适合希望深入了解 macOS 打包细节的开发者。
114 2
|
8月前
|
关系型数据库 MySQL iOS开发
macOS Catalina(10.15)如何访问iPhone(Ipad)的应用文档文件
macOS Catalina(10.15)如何访问iPhone(Ipad)的应用文档文件
234 0
|
8月前
|
Web App开发 iOS开发 MacOS
解决macOS 应用安装在下载目录时遇到的 vscode 掉登录和应用无法随机启动的问题
解决macOS 应用安装在下载目录时遇到的 vscode 掉登录和应用无法随机启动的问题
158 0
|
监控 机器人 程序员
【小工具】一键隐藏/显示MacOS的应用图标
【小工具】一键隐藏/显示MacOS的应用图标
|
iOS开发 MacOS
全网首发:(解决办法)MAC OS Xcode给应用设置沙箱(Enable App Sandbox)之后,运行报错Illegal instruction: 4
全网首发:(解决办法)MAC OS Xcode给应用设置沙箱(Enable App Sandbox)之后,运行报错Illegal instruction: 4
778 0
全网首发:(解决办法)MAC OS Xcode给应用设置沙箱(Enable App Sandbox)之后,运行报错Illegal instruction: 4
|
Dart 安全 IDE
Flutter Web实战项目打造真正跨平台应用(windows,android,ios,linux,macos,web)
Flutter Web项目 Flutter 最近发布了 Flutter V2.5.1,其性能得到了很大提升,支持 Web、macOS、Android 和 iOS。 这就是为什么今天我们使用在 Web、macOS 应用、Android 和 iOS 应用上运行的 flutter 创建响应式博客主题。 此外,我们创建了一个具有自定义悬停动画的动画网络菜单。 最后,您将学习如何使用 Flutter 制作响应式应用程序。
596 0
Flutter Web实战项目打造真正跨平台应用(windows,android,ios,linux,macos,web)
|
Web App开发 Dart 安全
flutter制作博客展示平台,现已支持 Web、macOS 应用、Android 和 iOS
Flutter Blog Theme using Flutter | Web, macOS, Android, iOS Flutter 最近发布了 Flutter V2.5.1,其性能得到了很大提升,支持 Web、macOS、Android 和 iOS。 这就是为什么今天我们使用在 Web、macOS 应用、Android 和 iOS 应用上运行的 flutter 创建响应式博客主题。 此外,我们创建了一个具有自定义悬停动画的动画网络菜单。 最后,您将学习如何使用 Flutter 制作响应式应用程序。
395 0
|
Shell 开发工具 Android开发
如何在MacOS上创建第一个iOS Flutter应用
1.安装Flutter 2.设置iOS模拟器 3.在Flutter中创建一个Hello World应用
181 0
|
iOS开发 MacOS
MACOS,应用签名后就崩溃?
MACOS,应用签名后就崩溃?
158 0
|
iOS开发 MacOS
macOS开发之NSTableView的应用详解(三)
macOS开发之NSTableView的应用详解
546 0