就我而言,任务是使用0.5 pt(Retina 显示屏上 1 px)分隔符。似乎即使intercellSpacing
设置为.zero
(或在我的情况下为 0.5 pt)AppKit 在绘制选择时仍保留行之间的 1 pt 空间。
我最终通过子类化NSTableRowView
。使用自定义行,我可以将分隔符设置为任何高度。这是一个 Swift 4.2 示例:
class WelcomeRecentDocumentsView: View {
private lazy var tableView = TableView().autolayoutView()
private lazy var scrollView = ScrollView(tableView: tableView).autolayoutView()
override var intrinsicContentSize: NSSize {
return CGSize(width: 240, height: 400)
}
private var recentDocumentsURLs = (0 ..< 10).map { $0 }
}
extension WelcomeRecentDocumentsView: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return recentDocumentsURLs.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
return tableView.makeView(ItemView.self)
}
}
extension WelcomeRecentDocumentsView: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
// Returning custom RowView.
return RowView(separatorHeight: separatorHeight, separatorColor: tableView.gridColor)
}
}
extension WelcomeRecentDocumentsView {
private var separatorHeight: CGFloat {
return convertFromBacking(1)
}
override func setupUI() {
addSubview(scrollView)
let column = NSTableColumn(identifier: "com.example.column", resizingMask: .autoresizingMask)
tableView.addTableColumn(column)
tableView.columnAutoresizingStyle = .uniformColumnAutoresizingStyle
tableView.headerView = nil
tableView.setAutomaticRowHeight(estimatedHeight: ItemView.defaultHeight)
tableView.intercellSpacing = CGSize(height: separatorHeight)
tableView.gridStyleMask = .solidHorizontalGridLineMask
}
override func setupHandlers() {
tableView.delegate = self
tableView.dataSource = self
}
override func setupLayout() {
LayoutConstraint.pin(to: .bounds, scrollView).activate()
}
override func setupDefaults() {
tableView.sizeLastColumnToFit()
}
}
extension WelcomeRecentDocumentsView {
class RowView: NSTableRowView {
let separatorHeight: CGFloat
let separatorColor: NSColor
init(separatorHeight: CGFloat = 1, separatorColor: NSColor = .gridColor) {
self.separatorHeight = separatorHeight
self.separatorColor = separatorColor
super.init(frame: .zero)
}
required init?(coder decoder: NSCoder) {
fatalError()
}
override func drawSelection(in dirtyRect: NSRect) {
let rect = bounds.insetBottom(by: -separatorHeight)
NSColor.alternateSelectedControlColor.setFill()
rect.fill()
}
override func drawSeparator(in dirtyRect: NSRect) {
let rect = bounds.insetTop(by: bounds.height - separatorHeight)
separatorColor.setFill()
rect.fill()
}
}
class ItemView: View {
static let defaultHeight: CGFloat = 52
override var intrinsicContentSize: NSSize {
return CGSize(intrinsicHeight: type(of: self).defaultHeight)
}
}
}