趁着项目不紧张,赶紧武装一下自己,如果有一天移动开发混不下去了,还可以转转macOS开发(虽然它和iOS开发的区别很小),如果你是一名iOS的开发者,那么其实你已经掌握了很大一部分macOS的开发技巧了,我用的是Xcode9 + Swift4
我看的是Tutorials上的教程macOS Development Tutorials,一般的控件什么的看一下就可以了,用到的时候再细看。其中稍微有点难度的有NSTableView,NSCollectionView,还有就是macOS上特殊的交互拖拽操作。另外在学习macOS的开发过程中,发现了Cocoa binding这种数据绑定方法,可以让你在编写少量代码的情况下,主要通过Xcode操作绑定数据和UI,有兴趣的可以去看看Cocoa Bindings on macOS。
接下来就细细探究一下NSTableView的实现和踩到的一些坑吧。
从 Object Library拖一个table view放到一个view中,约束设置为(0,0,0,0)填满视图,看一下NSTableView的结构,图中的“Table Cell View”是删除原始的cell,然后从Object Library中拖的“Image & Text Table Cell View”,比原始cell多了一张图片。
- 每一列也可以有一个列头(header row),列头描述了这一列的数据
- 每一行代表在数据模型集合中的单独的一项
- 每一列展示这个model的指定的属性
如果要对table view的行数进行修改设置,选中table view而不是包含它的scroll view,在Attributes Inspector中改变 Columns 也就是列数,也可以重命名列的名称。
如果想一次操作多行数据,可以在 Selection 中勾选 Multiple ,同时在Highlight这里勾选Alternating Rows,当它打开时,table view就会使用交替的背景颜色,就像Finder文件列表一样,还有很多的设置有兴趣的可以看看。
相对于 UITableView,它的主要区别是你可以有多列,及一个可以用来同table view交互的表头,例如点击列头进行 排序 和 选取。
注:选中命名的cell名称,点击每个cell,在 Identity Inspector 中设定它的identifier,每个类型的cell都需要设置,接下来便是填充数据了。
- NSTableViewDataSource:告诉table view有多少行需要展示
- NSTableViewDelegate:提供将要展示在指定行和列上的cell
跟UItableView一样,实现两个协议中你需要的方法,只是方法名称略有差别 不要忘记设置tableview的代理
tableView.delegate = self
tableView.dataSource = self
复制代码
每一个类别的cell,设置CellIdentifier
fileprivate enum CellIdentifiers {
static let NameCell = "NameCellID"
static let DateCell = "DateCellID"
static let SizeCell = "SizeCellID"
}
复制代码
//返回列表行数
func numberOfRows(in tableView: NSTableView) -> Int
//获取每一行的cell
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
var image: NSImage?
var text: String = ""
var cellIdentifier: String = ""
//拿到模型中的数据存到item中
guard let item = directoryItems?[row] else {
return nil
}
//判断所在列
if tableColumn == tableView.tableColumns[0] {
image = item.icon
text = item.name
cellIdentifier = CellIdentifiers.NameCell
}else if tableColumn == tableView.tableColumns[1] {
text = dateFormatter.string(from: item.date)
cellIdentifier = CellIdentifiers.DateCell
}else if tableColumn == tableView.tableColumns[2] {
text = item.isFolder ? "--" : sizeFormatter.string(fromByteCount: item.size)
cellIdentifier = CellIdentifiers.SizeCell
}
//调用 make(withIdentifier:owner:) 来得到一个cell。这个方法通过那个identifier来创建或复用一个cell,然后使用之前提供的数据来填充它
if let cell = tableView.make(withIdentifier: cellIdentifier, owner: nil) as? NSTableCellView {
cell.textField?.stringValue = text
cell.imageView?.image = image ?? nil
return cell
}
return nil
}
复制代码
相信只要接触iOS开发的都能看出来和UITableView的大同小异了,下面再介绍其他NSTbaleView的协议方法
NSTbaleView内容选择发生改变时调用
func tableViewSelectionDidChange(_ notification: Notification)
复制代码
doubleAction属性是双击cell时触发,同时需要设置target
tableView.target = self
tableView.doubleAction = #selector(tableViewDoubleClick(_:))
复制代码
当用户点击任一列头时,这个table view会调用此方法基于提供的descriptor来进行排序。
func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor])
复制代码
最终的效果图是这样的
详细的demo代码可以去我的github下载查看,FileViewer。