swift - 使用 - (BOOL)tableView:isGroupRow 时,NSAttributedString 的格式在 NSTableCellView / NSTableView 中消失:
问题描述
我正在使用一个应用程序,我想将 NSTableView 中的所有单元格组合起来作为其下方行的节标题。我正在使用的一种解决方案是使用 - (BOOL)tableView:isGroupRow: 这在一定程度上起作用,但不幸的是,我在 NSTextField 上使用的格式在使用 isGroupRow 时会被破坏,文本应该是白色的,并且无论是否显示粗体不管我设置与否。
在示例代码中,如果您取消注释该行// return false
,tableView(_ tableView: NSTableView, isGroupRow row: Int)
您将看到正确的格式正常工作(当然该字段显示两次,因为它没有被转换为组行
该解决方案需要几个步骤,完整的示例项目可以在https://github.com/jcnolan/NSTableViewIsGroupRowTest找到
这是我的 tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
var text: String = "Doh!"
var aText: NSAttributedString? = nil
var cellIdentifier: CellIdentifiers? = nil
guard let item = tableData?[row] else { return nil }
if let tableColumn = tableColumn { cellIdentifier = CellIdentifiers(rawValue: String(describing: tableColumn.identifier.rawValue)) }
else { cellIdentifier = CellIdentifiers.pageCell } // When "groupRow" is true there is no column, so use first column whatever that is
if let _ = item.title { cellIdentifier = CellIdentifiers.titleRow } // hack
guard let cellIdentifier = cellIdentifier else { return nil }
if let cell = tableView.makeView(withIdentifier: cellIdentifier.uiiId, owner: nil) as? NSTableCellView {
switch cellIdentifier {
case .pageCell: text = item.page?.description ?? "page unk"; break
case .commentCell: text = item.comment ?? "comment unk"; break
case .titleRow: text = item.title ?? "title unk"
var attributes = [NSAttributedString.Key: AnyObject]()
attributes[.foregroundColor] = NSColor.white
attributes[.font] = NSFont.boldSystemFont(ofSize: 13.0)
aText = NSAttributedString(string: text, attributes: attributes)
}
if let aText = aText { cell.textField?.attributedStringValue = aText }
else { cell.textField?.stringValue = text }
return cell
}
return nil
}
而我的 tableView(_ tableView: NSTableView, isGroupRow row: Int)
func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
// return false // Uncomment this to see NSAttributedString working in standard row
guard let item = tableData?[row], let title = item.title else { return false }
return true // only if item exists and it's a tittle
}
该解决方案还需要 func tableView(_ tableView: NSTableView, rowViewForRow row: Int)
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
// Required for changing table highlighting
guard let item = tableData?[row] else { return nil }
let retVal:TintedTableRowView? = TintedTableRowView()
if let retVal = retVal {
retVal.isTitleRow = item.title != nil
}
return retVal
}
class TintedTableRowView: NSTableRowView {
var isTitleRow: Bool = false
override func draw(_ dirtyRect: NSRect) {
if self.selectionHighlightStyle != .none || true {
var bgcol:NSColor = NSColor.clear
switch isTitleRow {
case true: bgcol = NSColor.lightGray
default: bgcol = NSColor.clear }
let selectionRect = NSInsetRect(self.bounds, 0, 0)
bgcol.setStroke()
bgcol.setFill()
let selectionPath = NSBezierPath.init(roundedRect: selectionRect, xRadius: 0, yRadius: 0)
selectionPath.fill()
selectionPath.stroke()
}
}
}
基于字体自动加粗的事实,我猜还需要另一条路径来告诉 Swift 如何格式化组行?我已经为这个问题苦苦挣扎了好几天了......任何帮助将不胜感激。
编辑:检查文档有一个参考“当配置为源列表样式表视图时,标识为组行的行以源列表独有的特定样式绘制。” 但是,我没有使用“源列表”样式并在情节提要编辑器和通过代码中将其显式更改为“普通”似乎没有效果。
EDIT2:对数据集提出了额外的请求......虽然我很确定这与 isGroupRow 有关,完整的项目可以在https://github.com/jcnolan/NSTableViewIsGroupRowTest看到。这是数据集和 viewDidLoad():
struct TableDataItem {
var title: String? = nil
var page: Int? = nil
var comment: String? = nil
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
tableView.dataSource = self
tableView.floatsGroupRows = false
installStubData()
tableView.reloadData()
}
func installStubData() {
tableData = []
tableData!.append(TableDataItem(title: "This is doc title 1", page: nil, comment: nil))
tableData!.append(TableDataItem(title: nil, page: 1, comment: "this is doc 1, page one comment"))
tableData!.append(TableDataItem(title: nil, page: 2, comment: "this is doc 1, page two comment"))
tableData!.append(TableDataItem(title: nil, page: 3, comment: "this is doc 1, page three comment"))
tableData!.append(TableDataItem(title: "This is doc title 2", page: nil, comment: nil))
tableData!.append(TableDataItem(title: nil, page: 1, comment: "this is doc 2, page one comment"))
tableData!.append(TableDataItem(title: "This is doc title 3", page: nil, comment: nil))
tableData!.append(TableDataItem(title: nil, page: 1, comment: "this is doc 3, page one comment"))
tableData!.append(TableDataItem(title: nil, page: 2, comment: "this is doc 3, page two comment"))
}
解决方案
推荐阅读
- javascript - Node.js如何将pg数据库中的数据保存到变量中
- ansible - CentOS Stream 8 似乎不支持 Ansible tower/awx 3.8.3
- actionscript-3 - 如何根据动态文本的宽度创建动态下三分之一 i AS3
- playwright - Playwright 测试运行器:将测试限制为仅一个浏览器,其配置文件包含许多项目
- css - 打字机效果全幅
- jenkins - Jenkins 错误:在构建时找不到名为 toolbelt 的工具
- api - 是否有任何选项可以通过 PushBullet API 获取最后传入的短信?
- javascript - 如何从 JS 文件中的 groovy 控制器访问返回的对象
- selenium - XPATH 文本设置基于语言的动态值
- mysql - 在 Apache Superset SQL LAB 中计算同比增长时在查询中添加过滤器列