轉(zhuǎn)載請(qǐng)聯(lián)系作者獲取授權(quán),并標(biāo)明文章作者,謝謝!
一、前言
本文所有代碼基于Xcode8.3.3,Swift3.0開發(fā)。
NSTableView是macOS開發(fā)中很重要的控件,用于滾動(dòng)數(shù)據(jù),表格數(shù)據(jù)等復(fù)雜視圖的實(shí)現(xiàn)。首先如果想要實(shí)現(xiàn)NSTableView的滾動(dòng)效果需要將它承載在一個(gè)NSScrollView里。和iOS中的UITableView類似數(shù)據(jù)源也是DataSource,視圖屬性也是由Delegate控制。
在OS X v10.6版本之前,NSTableView中行數(shù)據(jù)載體視圖必須是NSCell的子類,之后版本的OS X支持開發(fā)者創(chuàng)建基于View的TableView視圖,同樣也支持基于Cell的TabelView視圖,在開發(fā)者,我們可以根據(jù)實(shí)際需求選擇。
二、構(gòu)建一個(gè)簡(jiǎn)單的NSTableView視圖
創(chuàng)建一個(gè)WindowVC在里面構(gòu)建NSTableView。
關(guān)于NSWindowController的簡(jiǎn)述和創(chuàng)建請(qǐng)看這篇文章:NSWindowController。
private lazy var tableView: NSTableView = {
let tmpTableView = NSTableView()
tmpTableView.delegate = self
tmpTableView.dataSource = self
tmpTableView.allowsColumnSelection = true
return tmpTableView
}()
var dataSource = Array<Any>()
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
//初始化數(shù)據(jù)源
for i in 0..<10{
let dataStr = "第\(i+1)條數(shù)據(jù)"
dataSource.append(dataStr)
}
//初始化ScrollView用于承載tableView附有滾動(dòng)效果
let scrollView = NSScrollView()
scrollView.hasVerticalScroller = true
scrollView.frame = CGRect.zero
self.window?.contentView?.addSubview(scrollView)
scrollView.snp.makeConstraints { (make) in
make.edges.equalTo(0)
}
//初始化兩個(gè)column
let column1 = NSTableColumn(identifier: "test1")
column1.width = 200
column1.minWidth = 200
column1.maxWidth = 201
column1.title = "column1"
let column2 = NSTableColumn(identifier: "test2")
column2.width = 200
column2.minWidth = 200
column2.maxWidth = 201
column2.title = "column2"
column2.isEditable = true
column2.headerToolTip = "提示"
column2.isHidden = false
column2.sortDescriptorPrototype = NSSortDescriptor(key: "sortDescriptorPrototyp", ascending: false)
//允許自動(dòng)調(diào)整Column的尺寸
column1.resizingMask = NSTableColumnResizingOptions.autoresizingMask
column2.resizingMask = NSTableColumnResizingOptions.autoresizingMask
tableView.frame = CGRect.zero
tableView.addTableColumn(column1)
tableView.addTableColumn(column2)
scrollView.contentView.documentView = tableView
tableView.snp.makeConstraints { (make) in
make.top.left.right.equalTo(0)
}
}
下面是代理方法的實(shí)現(xiàn):
func numberOfRows(in tableView: NSTableView) -> Int {
return 10
}
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
return 40
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
var rowStr = ""
if tableColumn?.identifier == "test1" {
rowStr += "第1列,"
}else if tableColumn?.identifier == "test2" {
rowStr += "第2列,"
}
rowStr += (dataSource[row] as! String)
return rowStr
}
func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
print("oldDescriptors[0] -> (sortDescriptorPrototyp, descending, compare:)")
}
工程運(yùn)行效果如下圖:

我們來(lái)分析一下這個(gè)tableView的實(shí)現(xiàn):這是一個(gè)典型的基于Cell-Base的NSTableView,數(shù)據(jù)核心代碼是<code>objectValueFor tableColumn:</code>方法,和UITableView一樣需要實(shí)現(xiàn)<code>numberOfRows,heightOfRow</code>方法,在<code>objectValueFor tableColumn:</code>方法中我們可以通過(guò)<code>tableColumn?.identifier</code>來(lái)指定我們之前添加的NSColumn從而可以確定每一列的每一行數(shù)據(jù)。
三、關(guān)于NSColumn
NSColumn可以理解為NSTableView的一列,我們可以給某一列設(shè)置一些屬性(寬度,標(biāo)題,編輯狀態(tài)...等)。下面列舉NSColumn的常用屬性。
//初始化方法,指定一個(gè)列ID
public init(identifier: String)
//與此列關(guān)聯(lián)的ID
open var identifier: String
//關(guān)聯(lián)的TableView
unowned(unsafe) open var tableView: NSTableView?
//設(shè)置列寬度
open var width: CGFloat
//設(shè)置最小列寬度
open var minWidth: CGFloat
//設(shè)置最大列寬度
open var maxWidth: CGFloat
//設(shè)置類標(biāo)題
open var title: String
/*
列標(biāo)題視圖 開發(fā)者可以對(duì)其進(jìn)行修改
需要注意,NSTableHeaderCell是繼承自NSTextFieldCell
*/
open var headerCell: NSTableHeaderCell
//設(shè)置此列是否可以進(jìn)行編輯
open var isEditable: Bool
//進(jìn)行列尺寸的調(diào)整 以列標(biāo)題視圖的寬度為標(biāo)準(zhǔn)
open func sizeToFit()
//提供了這個(gè)屬性,會(huì)在列標(biāo)題那里顯示一個(gè)排序按鈕 點(diǎn)擊列標(biāo)題后可以進(jìn)行排序操作(會(huì)回調(diào)相關(guān)協(xié)議方法)
@NSCopying open var sortDescriptorPrototype: NSSortDescriptor?
//設(shè)置列尺寸的調(diào)整模式 枚舉如下
/*
public struct NSTableColumnResizingOptions : OptionSet {
public init(rawValue: UInt)
public static var autoresizingMask: NSTableColumnResizingOptions { get } //使用tableView的column調(diào)整策略
public static var userResizingMask: NSTableColumnResizingOptions { get }//允許用戶進(jìn)行尺寸調(diào)整
}
*/
open var resizingMask: NSTableColumnResizingOptions
//設(shè)置列頭的提示標(biāo)題 當(dāng)鼠標(biāo)懸停在類標(biāo)題上時(shí) 會(huì)顯示此提示
open var headerToolTip: String?;
//設(shè)置此列是否隱藏
open var isHidden: Bool
//設(shè)置此列所有行的數(shù)據(jù)載體視圖 如果不設(shè)置 默認(rèn)為NSTextFieldCell
open var dataCell: Any
//為TableView列表提供數(shù)據(jù)載體視圖
open func dataCell(forRow row: Int) -> Any
四、Cell-Base:基于Cell的NSTableView
Cell-Base的NSTableView是macOS早起開發(fā)的主要結(jié)構(gòu),其每一個(gè)載體都必須是基于NSCell或者其子類,必須實(shí)現(xiàn)<code> numberOfRows </code>和<code>objectValueFor tableColumn</code>兩個(gè)方法。第一個(gè)方法設(shè)置行數(shù),第二個(gè)給每個(gè)Cell載體賦予數(shù)據(jù)。需要注意,如果只實(shí)現(xiàn)這兩個(gè)方法,則NSTableView會(huì)自動(dòng)從列對(duì)象NSTableColume中取具體的行視圖,通過(guò)dataCellForRow方法。
當(dāng)<code>objectValueForTableColum </code>方法將每個(gè)行具體的數(shù)據(jù)返回后,編輯時(shí)會(huì)調(diào)用cell的<code>setObjectValue</code>方法(因此如果要自定義cell,必須實(shí)現(xiàn)這個(gè)方法)。如果我們要對(duì)Cell的渲染進(jìn)行一些定制,可以在如下方法中實(shí)現(xiàn):
//cell-base的cell展示前調(diào)用 可以進(jìn)行自定制
func tableView(_ tableView: NSTableView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, row: Int) {
let tmpCell = cell as! NSTextFieldCell
tmpCell.textColor = NSColor.red
}
實(shí)現(xiàn)下面的方法可以返回一個(gè)自定義的Cell,如果實(shí)現(xiàn)了這個(gè)方法,則TableView不會(huì)再?gòu)腘STableColumn對(duì)象中拿Cell實(shí)例。
//自定義cell
func tableView(_ tableView: NSTableView, dataCellFor tableColumn: NSTableColumn?, row: Int) -> NSCell? {
if tableColumn != nil{
let cell = MyCell()
return cell
}
return nil
}
全部代碼如下:(NSTalbeView和NSScrollView的創(chuàng)建以及屬性和上方示例1代碼一樣,故下方只列舉代理方法)
//設(shè)置行數(shù) 通用
func numberOfRows(in tableView: NSTableView) -> Int {
return 10
}
//設(shè)置行高度 通用
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
return 40
}
//綁定數(shù)據(jù)源
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
var rowStr = ""
if tableColumn?.identifier == "test1" {
rowStr += "第1列,"
}else if tableColumn?.identifier == "test2" {
rowStr += "第2列,"
}
rowStr += (dataSource[row] as! String)
return rowStr
}
//排序回調(diào)函數(shù)
func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
print("oldDescriptors[0] -> (sortDescriptorPrototyp, descending, compare:)")
}
//cell-base的cell展示前調(diào)用 可以進(jìn)行自定制
func tableView(_ tableView: NSTableView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, row: Int) {
let tmpCell = cell as! NSTextFieldCell
tmpCell.textColor = NSColor.red
}
//設(shè)置是否可以進(jìn)行編輯
func tableView(_ tableView: NSTableView, shouldEdit tableColumn: NSTableColumn?, row: Int) -> Bool {
if tableColumn?.identifier == "test1" {
return true
}
return false
}
//用戶編輯列表
func tableView(_ tableView: NSTableView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, row: Int) {
print("\(object as! String)")
dataSource[row] = object as! String
}
//設(shè)置鼠標(biāo)懸停在cell上顯示的提示文本
func tableView(_ tableView: NSTableView, toolTipFor cell: NSCell, rect: NSRectPointer, tableColumn: NSTableColumn?, row: Int, mouseLocation: NSPoint) -> String {
if tableColumn?.identifier == "test2" {
return dataSource[row] as! String
}
return ""
}
//當(dāng)列表長(zhǎng)度無(wú)法展示完整某行數(shù)據(jù)時(shí) 當(dāng)鼠標(biāo)懸停在此行上 是否擴(kuò)展顯示
func tableView(_ tableView: NSTableView, shouldShowCellExpansionFor tableColumn: NSTableColumn?, row: Int) -> Bool {
return true
}
//設(shè)置cell的交互能力
/*
如果返回YES,則Cell的交互能力會(huì)變強(qiáng),例如NSButtonCell的點(diǎn)擊將會(huì)調(diào)用- (void)tableView:(NSTableView *)tableView setObjectValue方法
*/
func tableView(_ tableView: NSTableView, shouldTrackCell cell: NSCell, for tableColumn: NSTableColumn?, row: Int) -> Bool {
return true
}
//自定義cell
func tableView(_ tableView: NSTableView, dataCellFor tableColumn: NSTableColumn?, row: Int) -> NSCell? {
if tableColumn != nil{
let cell = MyCell()
return cell
}
return nil
}
五、View-Base:基于View的NSTableView
基于View-Base的NSTableView則要更加靈活,它可以是任意NSView的子類來(lái)作為NSTableView的載體,書寫方式,自定義方式等更加簡(jiǎn)單易用,示例代碼:
//設(shè)置行數(shù) 通用
func numberOfRows(in tableView: NSTableView) -> Int {
return 10
}
//設(shè)置行高度 通用
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
return 40
}
//View-base
//設(shè)置某個(gè)元素的具體視圖
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let key = tableColumn?.identifier
//根據(jù)ID取視圖
var view = tableView.make(withIdentifier: "cellId", owner: self)
if (view==nil) {
view = NSTextField()
(view as! NSTextField).isBordered=false
(view as! NSTextField).isEditable=false
(view as! NSTextField).backgroundColor = NSColor.clear
(view as! NSTextField).identifier = "cellId";
}
(view as! NSTextField).stringValue = "Identifier為:\(key!)列的數(shù)據(jù),\(dataSource[row])"
return view;
}
//設(shè)置每行容器視圖
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
let tableRowView = TableRow()
let lineView = NSView()
lineView.wantsLayer = true
lineView.layer?.backgroundColor = NSColor.blue.cgColor
tableRowView.addSubview(lineView)
lineView.snp.makeConstraints { (make) in
make.left.right.bottom.equalTo(0)
make.height.equalTo(1)
}
return tableRowView
}
//當(dāng)添加行時(shí)調(diào)用的回調(diào)
func tableView(_ tableView: NSTableView, didAdd rowView: NSTableRowView, forRow row: Int) {
print("addRow")
}
//當(dāng)移除行時(shí)調(diào)用的回調(diào)
func tableView(_ tableView: NSTableView, didRemove rowView: NSTableRowView, forRow row: Int) {
print("removeRow")
}
下面是運(yùn)行效果:

上面代碼中用到了TableRow類,其實(shí)它是一個(gè)自定義的繼承自NSTableRowView的類,實(shí)現(xiàn)如下:
import Cocoa
class TableRow: NSTableRowView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//繪制選中狀態(tài)的背景
override func drawSelection(in dirtyRect: NSRect) {
let selectionRect = NSInsetRect(self.bounds, 5.0, 5.0)
NSColor.init(calibratedWhite: 72, alpha: 0.6).setStroke()
NSColor.init(calibratedWhite: 82, alpha: 0.6).setFill()
let selectionPath = NSBezierPath.init(roundedRect: selectionRect, xRadius: 10, yRadius: 10)
selectionPath.fill()
selectionPath.stroke()
}
//繪制背景
override func drawBackground(in dirtyRect: NSRect) {
super.drawBackground(in: dirtyRect)
NSColor.green.setFill()
NSRectFill(dirtyRect)
}
}
NSTableRowView相當(dāng)于基于View-Base NSTableView的容器所在,它承載著所有的View。通過(guò)斷點(diǎn)調(diào)試發(fā)現(xiàn)在每次初始化某個(gè)元素的具體視圖之前都先調(diào)用初始化容器視圖的方法,先把容器造好,再往里面加視圖。例如上方代碼:兩列十行,每次先調(diào)用一次<code> rowViewForRow </code>方法把每行的容器造好然后再調(diào)用兩次<code>viewFor tableColumn</code>方法來(lái)添加具體的視圖。
六、關(guān)于NSTableRowView
NSTableRowView是基于View-Base的容器所在,在面介紹一些常用的屬性及方法。
//選中的高亮風(fēng)格
open var selectionHighlightStyle: NSTableViewSelectionHighlightStyle
//是否強(qiáng)調(diào)
open var isEmphasized: Bool
//設(shè)置是否行組風(fēng)格
open var isGroupRowStyle: Bool
//是否選中狀態(tài)
open var isSelected: Bool
//其前一行的選中狀態(tài)
@available(OSX 10.10, *)
open var isPreviousRowSelected: Bool
//其后一行的選中狀態(tài)
open var isNextRowSelected: Bool
//設(shè)置此行是否浮動(dòng)
open var isFloating: Bool
//拖放拖動(dòng)效果
open var isTargetForDropOperation: Bool
//拖放風(fēng)格
open var draggingDestinationFeedbackStyle:
//設(shè)置拖放目標(biāo)的縮進(jìn)量
open var indentationForDropOperation: CGFloat
//背景風(fēng)格
open var interiorBackgroundStyle: NSBackgroundStyle { get }
//背景色
@NSCopying open var backgroundColor: NSColor
//子類重寫下面方法來(lái)進(jìn)行行容器視圖的自定義
//畫背景色
open func drawBackground(in dirtyRect: NSRect)
//畫選中背景
open func drawSelection(in dirtyRect: NSRect)
//畫分割線
open func drawSeparator(in dirtyRect: NSRect)
//制拖放時(shí)的用戶反饋IU
open func drawDraggingDestinationFeedback(in dirtyRect: NSRect)
//提供的訪問特定視圖的方法
open func view(atColumn column: Int) -> Any?
//列數(shù)
open var numberOfColumns: Int { get }
七、總結(jié)NSTableViewDataSource協(xié)議
//無(wú)論是基于Cell還是基于View這個(gè)是必須實(shí)現(xiàn)的方法,設(shè)置行數(shù)
optional public func numberOfRows(in tableView: NSTableView) -> Int
//如果使用cell-base的TableView視圖,這個(gè)方法是必須實(shí)現(xiàn)的,其為要渲染的cell提供數(shù)據(jù)
optional public func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any?
//這個(gè)函數(shù)當(dāng)用戶編輯了cell中的內(nèi)容時(shí)會(huì)被調(diào)用,一般需要在其中進(jìn)行數(shù)據(jù)源的修改
optional public func tableView(_ tableView: NSTableView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, row: Int)
//當(dāng)用戶修改了行排序規(guī)則時(shí)調(diào)用的回調(diào)
optional public func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor])
//面這些方法全部與列表的數(shù)據(jù)拖拽相關(guān),具體可以參考Xcode文檔
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting?
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet)
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation)
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, updateDraggingItemsForDrag draggingInfo: NSDraggingInfo)
optional public func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool
optional public func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation
optional public func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool
optional public func tableView(_ tableView: NSTableView, namesOfPromisedFilesDroppedAtDestination dropDestination: URL, forDraggedRowsWith indexSet: IndexSet) -> [String]
八、總結(jié)NSTableViewDelegate協(xié)議
//基于View-Base的NSTableView相關(guān)Delegate方法
//設(shè)置每個(gè)數(shù)據(jù)載體的View
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?
//設(shè)置每行的容器視圖
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView?
//添加行的方法
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, didAdd rowView: NSTableRowView, forRow row: Int)
//刪除行的方法
@available(OSX 10.7, *)
optional public func tableView(_ tableView: NSTableView, didRemove rowView: NSTableRowView, forRow row: Int)
--------------------------------------這難道是分割線? --------------------------------------
//基于Cell-Base的NSTableView相關(guān)Delegate方法
//ell將要渲染時(shí)調(diào)用的回調(diào),可以在其中對(duì)cell進(jìn)行定制
optional public func tableView(_ tableView: NSTableView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, row: Int)
//設(shè)置某個(gè)cell是否可以編輯
optional public func tableView(_ tableView: NSTableView, shouldEdit tableColumn: NSTableColumn?, row: Int) -> Bool
//設(shè)置當(dāng)鼠標(biāo)懸停在cell上時(shí) 顯示的提示文案
optional public func tableView(_ tableView: NSTableView, toolTipFor cell: NSCell, rect: NSRectPointer, tableColumn: NSTableColumn?, row: Int, mouseLocation: NSPoint) -> String
//當(dāng)cell的寬度不夠顯示完全cell的內(nèi)容時(shí),設(shè)置是否允許鼠標(biāo)放置擴(kuò)展cell
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, shouldShowCellExpansionFor tableColumn: NSTableColumn?, row: Int) -> Bool
//設(shè)置是否加強(qiáng)cell的交互能力,這樣一些按鈕狀態(tài)的修改也會(huì)觸發(fā)cell編輯的狀態(tài)
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, shouldTrackCell cell: NSCell, for tableColumn: NSTableColumn?, row: Int) -> Bool
//設(shè)置自定義cell
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, dataCellFor tableColumn: NSTableColumn?, row: Int) -> NSCell?
--------------------------------------這難道是分割線? --------------------------------------
//通用的代理方法
//設(shè)置是否允許修改選中
optional public func selectionShouldChange(in tableView: NSTableView) -> Bool
//設(shè)置某行是否可以選中
optional public func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool
//當(dāng)用戶通過(guò)鍵盤或鼠標(biāo)將要選中某行時(shí),返回設(shè)置要選中的行,如果實(shí)現(xiàn)了這個(gè)方法,上面一個(gè)方法將不會(huì)被調(diào)用
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, selectionIndexesForProposedSelection proposedSelectionIndexes: IndexSet) -> IndexSet
//設(shè)置某列是否可以被選中
optional public func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool
//用戶點(diǎn)擊列頭時(shí)調(diào)用的方法
optional public func tableView(_ tableView: NSTableView, mouseDownInHeaderOf tableColumn: NSTableColumn)
//用法同上
optional public func tableView(_ tableView: NSTableView, didClick tableColumn: NSTableColumn)
//對(duì)列進(jìn)行拖拽改變順序時(shí)調(diào)用的方法
optional public func tableView(_ tableView: NSTableView, didDrag tableColumn: NSTableColumn)
//設(shè)置行高
optional public func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat
//下面這些方法與行檢索有關(guān)
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, typeSelectStringFor tableColumn: NSTableColumn?, row: Int) -> String?
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, nextTypeSelectMatchFromRow startRow: Int, toRow endRow: Int, for searchString: String) -> Int
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, shouldTypeSelectFor event: NSEvent, withCurrentSearch searchString: String?) -> Bool
//設(shè)置某行是否繪制成組樣式
@available(OSX 10.5, *)
optional public func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool
//調(diào)整列寬度(本人測(cè)試時(shí)這個(gè)方法怎么也不調(diào)用,望大神指點(diǎn))
@available(OSX 10.6, *)
optional public func tableView(_ tableView: NSTableView, sizeToFitWidthOfColumn column: Int) -> CGFloat
//設(shè)置是否支持列的移動(dòng)排序
@available(OSX 10.6, *)
optional public func tableView(_ tableView: NSTableView, shouldReorderColumn columnIndex: Int, toColumn newColumnIndex: Int) -> Bool
////設(shè)置某行向左或向右滑動(dòng)時(shí)要顯示的功能按鈕
@available(OSX 10.11, *)
optional public func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableRowActionEdge) -> [NSTableViewRowAction]
//TableView選中修改時(shí)調(diào)用
optional public func tableViewSelectionDidChange(_ notification: Notification)
//TableView列移動(dòng)完成時(shí)調(diào)用的函數(shù)
optional public func tableViewColumnDidMove(_ notification: Notification)
//TableView列寬度變化時(shí)調(diào)用的函數(shù)
optional public func tableViewColumnDidResize(_ notification: Notification)
//TableView選中正在修改時(shí)調(diào)用的函數(shù)
optional public func tableViewSelectionIsChanging(_ notification: Notification)
九、NSTableView中常用的屬性和方法
//構(gòu)造方法
public init(frame frameRect: NSRect)
public init?(coder: NSCoder)
//數(shù)據(jù)源和代理
weak open var dataSource: NSTableViewDataSource?
weak open var delegate: NSTableViewDelegate?
//設(shè)置頭視圖,會(huì)被列頭圖就行覆蓋
open var headerView: NSTableHeaderView?
//設(shè)置頭圖右側(cè)視圖 可以自定義圖標(biāo)
open var cornerView: NSView?
//設(shè)置是否允許列拖拽排序
open var allowsColumnReordering: Bool
//設(shè)置是否允許調(diào)整列寬度
open var allowsColumnResizing: Bool
//調(diào)整列寬度的風(fēng)格
open var columnAutoresizingStyle: NSTableViewColumnAutoresizingStyle
//設(shè)置分割線風(fēng)格
open var gridStyleMask: NSTableViewGridLineStyle
//設(shè)置cell之間的間隔 需要設(shè)置為NSSize對(duì)象
open var intercellSpacing: NSSize
//是否開啟斑馬線
open var usesAlternatingRowBackgroundColors: Bool
//背景顏色
@NSCopying open var backgroundColor: NSColor
//設(shè)置分割線顏色
@NSCopying open var gridColor: NSColor
//設(shè)置尺寸風(fēng)格
@available(OSX 10.7, *)
open var rowSizeStyle: NSTableViewRowSizeStyle
//設(shè)置有效的行類型
@available(OSX 10.7, *)
open var effectiveRowSizeStyle: NSTableViewRowSizeStyle { get }
//行高
open var rowHeight: CGFloat
//記錄行高度的改變
open func noteHeightOfRows(withIndexesChanged indexSet: IndexSet)
//獲取所有列
open var tableColumns: [NSTableColumn] { get }
//列的個(gè)數(shù)
open var numberOfColumns: Int { get }
//行的個(gè)數(shù)
open var numberOfRows: Int { get }
//添加列
open func addTableColumn(_ tableColumn: NSTableColumn)
//刪除列
open func removeTableColumn(_ tableColumn: NSTableColumn)
//移動(dòng)列
open func moveColumn(_ oldIndex: Int, toColumn newIndex: Int)
//根據(jù)identifier獲取某個(gè)列對(duì)象的下表
open func column(withIdentifier identifier: String) -> Int
//根據(jù)identifier獲取某個(gè)列對(duì)象
open func tableColumn(withIdentifier identifier: String) -> NSTableColumn?
//標(biāo)題
open func tile()
//進(jìn)行自動(dòng)尺寸的調(diào)整
open func sizeToFit()
//進(jìn)行最后一列尺寸的調(diào)整
open func sizeLastColumnToFit()
//滾動(dòng)到指定行可見
open func scrollRowToVisible(_ row: Int)
//滾動(dòng)到指定列可見
open func scrollColumnToVisible(_ column: Int)
//重新加載數(shù)據(jù)
open func reloadData()
//記錄行數(shù)的改變
open func noteNumberOfRowsChanged()
//重新加載指定位置的數(shù)據(jù)
@available(OSX 10.6, *)
open func reloadData(forRowIndexes rowIndexes: IndexSet, columnIndexes: IndexSet)
//獲取編輯的列
open var editedColumn: Int { get }
//獲取編輯的行
open var editedRow: Int { get }
//獲取點(diǎn)擊的列
open var clickedColumn: Int { get }
//獲取點(diǎn)擊的行
open var clickedRow: Int { get }
//設(shè)置雙擊方法
open var doubleAction: Selector?
//排序回調(diào)函數(shù)
open var sortDescriptors: [NSSortDescriptor]
//設(shè)置列頭提示圖片
open func setIndicatorImage(_ image: NSImage?, in tableColumn: NSTableColumn)
//獲取列頭提示圖片
open func indicatorImage(in tableColumn: NSTableColumn) -> NSImage?
//獲取高亮的列
unowned(unsafe) open var highlightedTableColumn: NSTableColumn?
//下面這些方法與列表拖拽有關(guān)
open var verticalMotionCanBeginDrag: Bool
open func canDragRows(with rowIndexes: IndexSet, at mouseDownPoint: NSPoint) -> Bool
open func dragImageForRows(with dragRows: IndexSet, tableColumns: [NSTableColumn], event dragEvent: NSEvent, offset dragImageOffset: NSPointPointer) -> NSImage
open func setDraggingSourceOperationMask(_ mask: NSDragOperation, forLocal isLocal: Bool)
open func setDropRow(_ row: Int, dropOperation: NSTableViewDropOperation)
//下面這些方法和列表選中有關(guān)
//是否支持多選
open var allowsMultipleSelection: Bool
//是否允許都不選中
open var allowsEmptySelection: Bool
//是否支持選中列 如果設(shè)置為YES 點(diǎn)擊列頭會(huì)將整列選中
open var allowsColumnSelection: Bool
//全選 用于子類重寫
open func selectAll(_ sender: Any?)
//全不選 用于子類重寫
open func deselectAll(_ sender: Any?)
//選中列
open func selectColumnIndexes(_ indexes: IndexSet, byExtendingSelection extend: Bool)
//選中行
open func selectRowIndexes(_ indexes: IndexSet, byExtendingSelection extend: Bool)
//獲取所有選中的index
open var selectedColumnIndexes: IndexSet { get }
//獲取所有選中的行
open var selectedRowIndexes: IndexSet { get }
//取消某列的選中
open func deselectColumn(_ column: Int)
//取消某行的選中
open func deselectRow(_ row: Int)
//獲取被選中的列
open var selectedColumn: Int { get }
//獲取被選中的行
open var selectedRow: Int { get }
//判斷某列是否被選中
open func isColumnSelected(_ column: Int) -> Bool
//判斷某行是否被選中
open func isRowSelected(_ row: Int) -> Bool
//獲取選中的列數(shù)
open var numberOfSelectedColumns: Int { get }
//獲取選中的行數(shù)
open var numberOfSelectedRows: Int { get }
//允許被選中
@available(OSX 10.5, *)
open var allowsTypeSelect: Bool
//設(shè)置選中的高亮狀態(tài)
@available(OSX 10.5, *)
open var selectionHighlightStyle: NSTableViewSelectionHighlightStyle
//設(shè)置拖拽風(fēng)格
@available(OSX 10.6, *)
open var draggingDestinationFeedbackStyle: NSTableViewDraggingDestinationFeedbackStyle
//獲取某列的位置尺寸
open func rect(ofColumn column: Int) -> NSRect
//獲取某行的位置尺寸
open func rect(ofRow row: Int) -> NSRect
//獲取某個(gè)范圍內(nèi)的列
@available(OSX 10.5, *)
open func columnIndexes(in rect: NSRect) -> IndexSet
//獲取某個(gè)范圍內(nèi)的行
open func rows(in rect: NSRect) -> NSRange
//獲取包含某個(gè)點(diǎn)的列
open func column(at point: NSPoint) -> Int
//獲取包含某個(gè)點(diǎn)的行
open func row(at point: NSPoint) -> Int
//獲取某個(gè)cell的位置尺寸
open func frameOfCell(atColumn column: Int, row: Int) -> NSRect
//自動(dòng)保存名字
open var autosaveName: String?
//是否自動(dòng)保存列
open var autosaveTableColumns: Bool
//更改列
open func editColumn(_ column: Int, row: Int, with event: NSEvent?, select: Bool)
//手動(dòng)繪制某行
open func drawRow(_ row: Int, clipRect: NSRect)
//繪制高亮選中狀態(tài)
open func highlightSelection(inClipRect clipRect: NSRect)
//手動(dòng)繪制網(wǎng)格
open func drawGrid(inClipRect clipRect: NSRect)
//手動(dòng)繪制背景色
open func drawBackground(inClipRect clipRect: NSRect)
//獲取某個(gè)位置的View,用于view-base
@available(OSX 10.7, *)
open func view(atColumn column: Int, row: Int, makeIfNecessary: Bool) -> NSView?
//獲取某行的視圖 用于view-base
@available(OSX 10.7, *)
open func rowView(atRow row: Int, makeIfNecessary: Bool) -> NSTableRowView?
//獲取某個(gè)View所在的行 用于view-base
@available(OSX 10.7, *)
open func row(for view: NSView) -> Int
//獲取某個(gè)View所在的列 用于view-base
@available(OSX 10.7, *)
open func column(for view: NSView) -> Int
//創(chuàng)建一個(gè)用于渲染的View 用于view-base
@available(OSX 10.7, *)
open func make(withIdentifier identifier: String, owner: Any?) -> NSView?
//列出可用的行視圖
@available(OSX 10.7, *)
open func enumerateAvailableRowViews(_ handler: (NSTableRowView, Int) -> Swift.Void)
//是否允許某行浮動(dòng)
@available(OSX 10.7, *)
open var floatsGroupRows: Bool
//是否隱藏左右滑動(dòng)時(shí)的功能按鈕
@available(OSX 10.11, *)
open var rowActionsVisible: Bool
//下面這些方法用來(lái)根據(jù)列表數(shù)據(jù)
//開始更新
@available(OSX 10.7, *)
open func beginUpdates()
//結(jié)束更新
@available(OSX 10.7, *)
open func endUpdates()
//插入行
@available(OSX 10.7, *)
open func insertRows(at indexes: IndexSet, withAnimation animationOptions: NSTableViewAnimationOptions = [])
//刪除行
@available(OSX 10.7, *)
open func removeRows(at indexes: IndexSet, withAnimation animationOptions: NSTableViewAnimationOptions = [])
//移動(dòng)行
@available(OSX 10.7, *)
open func moveRow(at oldIndex: Int, to newIndex: Int)
//隱藏行
@available(OSX 10.11, *)
open func hideRows(at indexes: IndexSet, withAnimation rowAnimation: NSTableViewAnimationOptions = [])
//取消隱藏行
@available(OSX 10.11, *)
open func unhideRows(at indexes: IndexSet, withAnimation rowAnimation: NSTableViewAnimationOptions = [])
//所有隱藏狀態(tài)的行
@available(OSX 10.11, *)
open var hiddenRowIndexes: IndexSet { get }
//注冊(cè)某個(gè)NSNib類進(jìn)行復(fù)用
@available(OSX 10.8, *)
open func register(_ nib: NSNib?, forIdentifier identifier: String)
//獲取注冊(cè)過(guò)的NSNib
@available(OSX 10.8, *)
open var registeredNibsByIdentifier: [String : NSNib]? { get }
//有行被添加時(shí)調(diào)用
@available(OSX 10.7, *)
open func didAdd(_ rowView: NSTableRowView, forRow row: Int)
//有行被移動(dòng)時(shí)調(diào)用
@available(OSX 10.7, *)
open func didRemove(_ rowView: NSTableRowView, forRow row: Int)
//是否將tableView設(shè)置成靜態(tài)
@available(OSX 10.10, *)
open var usesStaticContents: Bool
//用戶界面布局方向:枚舉類型
open var userInterfaceLayoutDirection: NSUserInterfaceLayoutDirection
總結(jié)
作者最近在學(xué)習(xí)macOS開發(fā),發(fā)現(xiàn)NSTableView是macOS開發(fā)中很重要的控件,它不僅功能強(qiáng)大而且官方為我們提供的接口更加更富,這讓我們學(xué)習(xí)起來(lái)容易入手,以上全是個(gè)人最近學(xué)習(xí)的總結(jié),如有不妥之處請(qǐng)指教,謝謝。
作者:Olivia_Zqy