實(shí)現(xiàn)一個(gè) NSTableView,NSTableCellVIew 根據(jù)內(nèi)容量和 window 寬度自動適應(yīng)高度。
NSTableView 和 UITableView 有很大不同。比如 iOS 在設(shè)置好 autolayout 之后就不用去管 cell 的高度了。但是 macOS 中仍然需要提供高度數(shù)據(jù)。其他諸如點(diǎn)擊事件,響應(yīng) cell 的背景色等等 api 也和 iOS 不一樣。由于 window 的大小可變,渲染圖形的時(shí)候要考慮到這種情況,不能依賴 autolayout 一勞永逸??傊?, macOS 要考慮的情況多一些,能找到的資料又相對欠缺。
NSTableView
Storyboard 中往 ViewController 拖入 NSTableView 控件,設(shè)置 autolayout 填滿視圖
中欄層級結(jié)構(gòu)圖中右鍵拖放 Table View 至 View Controller,連接 NSTableViewDelegate 和 NSTableViewDataSource
拖一個(gè) tableView 的 IBOutlet 引用至 ViewController
-
注冊 Cell
@IBOutlet weak var tableView: NSTableView!{ didSet{ let nib = NSNib(nibNamed: "CustomCell", bundle: nil) self.tableView.register(nib, forIdentifier: "CustomCell") } }
讓 Cell 填滿視圖寬度
- 選擇 table view 后,Attributes inspector 中設(shè)置 Columns: 1,去掉 Headers, Reordering, Resizing 選項(xiàng),Column Sizing: Uniform
- 如果顯示不正確,把 table view 拉到比兩個(gè) columns 還小的寬度,然后再拉回與 window 寬度同寬
NSTableCellView
- 新建 CustomCell.swift
- 新建 macOS > User Interface > Empty > CustomCell.xib,拖入 NSTableCellView,拖入一個(gè) Custom View 作為 contentView,之后所有的空間都放在這個(gè) contentView 上,稍后將用這個(gè) contentView 來獲得 cell 的高度
- Attribute Inspector 中設(shè)置 CustomCell.xib 的類為 CustomCell,identifier > CustomCell,拖 IBOutlet 至 CustomCell.swift
把值顯示到 cell 的兩種方式
1. 綁定 Object
- 選擇 Table Cell View,Bindings inspector > value > Bind to: Table Cell View,Model Key Path: objectValue
2. 給 NSTableCellView 實(shí)例賦值
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cell = tableView.make(withIdentifier: "CustomCell", owner: self) as! CustomCell
let item = dataSource?[row]
cell.setContent(item: item)
return cell
}
動態(tài)高度
通過容器視圖的 fittingSize 方法獲得高度
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
let cell = tableView.make(withIdentifier: "CustomCell", owner: self) as! CustomCell
let item = dataSource?[row]
cell.setContent(item: item)
return cell.contentView.fittingSize.height
}
收取窗口改變的通知,在 window 大小改變的時(shí)候 reloadData()。
NotificationCenter.default.addObserver(self, selector: #selector(receivedNotification(notification:)), name: NSNotification.Name.NSWindowDidResize, object: nil)
參考
- https://developer.apple.com/reference/appkit/nstableview
- http://stackoverflow.com/questions/7545490/how-can-i-have-the-only-column-of-my-nstableview-take-all-the-width-of-the-table
- https://www.youtube.com/watch?v=b6jQCLLPJ_8
- https://www.youtube.com/watch?v=iJHskQ27gVM
- https://ez-net.jp/article/00/jVzOXcdJ/C603m85YfWFm/
- http://sxiaojian.com/2015/08/11/Mac-NSTableView/
- http://stackoverflow.com/questions/22263603/how-to-get-the-height-of-an-nstablecellview-that-uses-autolayout