macOS Dev: NSTableView
2017-04-25 本文已影响0人
su3
实现一个 NSTableView,NSTableCellVIew 根据内容量和 window 宽度自动适应高度。
NSTableView 和 UITableView 有很大不同。比如 iOS 在设置好 autolayout 之后就不用去管 cell 的高度了。但是 macOS 中仍然需要提供高度数据。其他诸如点击事件,响应 cell 的背景色等等 api 也和 iOS 不一样。由于 window 的大小可变,渲染图形的时候要考虑到这种情况,不能依赖 autolayout 一劳永逸。总之, macOS 要考虑的情况多一些,能找到的资料又相对欠缺。
NSTableView
-
Storyboard 中往 ViewController 拖入 NSTableView 控件,设置 autolayout 填满视图
-
中栏层级结构图中右键拖放 Table View 至 View Controller,连接 NSTableViewDelegate 和 NSTableViewDataSource
-
拖一个 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 中设置 Columns: 1,去掉 Headers, Reordering, Resizing 选项,Column Sizing: Uniform
- 如果显示不正确,把 table view 拉到比两个 columns 还小的宽度,然后再拉回与 window 宽度同宽
NSTableCellView
- 新建 CustomCell.swift
- 新建 macOS > User Interface > Empty > CustomCell.xib,拖入 NSTableCellView,拖入一个 Custom View 作为 contentView,之后所有的空间都放在这个 contentView 上,稍后将用这个 contentView 来获得 cell 的高度
- Attribute Inspector 中设置 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 实例赋值
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
}
动态高度
通过容器视图的 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 大小改变的时候 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