我需要将文本包装在NSTable的行中。我读了: SO How to update row heights...
和: View-based NSTableView with rows that have dynamic height...
我的行高对于多行文本(带有eol)可以很好地工作,但是如果我不使用eol,行高度是可以的。 (使用精简的测试用例,直到我弄清楚为止。)
这是我的演示代码:
class TableCellView: NSTableCellView {
var title = NSTextField()
convenience init(_ id: NSUserInterfaceItemIdentifier, itemCount: Int) {
self.init(frame: .zero)
identifier = id
rowSizeStyle = .custom
addSubview(title)
var s = "\(itemCount):\n"
for item in 0...(5 + itemCount) { s += "\(item)) Text written to a scrollable table view " }
let a = NSAttributedString(string: s, attributes: [NSAttributedString.Key.font : NSFont.systemFont(ofSize: 18.0)] )
title.attributedStringValue = a
title.textColor = NSColor.textColor
title.backgroundColor = NSColor.clear
title.translatesAutoresizingMaskIntoConstraints = false
title.isBordered = false
title.widthAnchor.constraint(equalTo: widthAnchor, constant: 0).isActive = true
title.topAnchor.constraint(equalTo: topAnchor, constant: 1).isActive = true
title.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
}
class TableViewManager: NSObject, NSTableViewDataSource, NSTableViewDelegate, Actor {
weak var actorDelegate: ActorDelegate?
var identifier: NSUserInterfaceItemIdentifier? = Identifier.View.tableDelegate
var count = 0
func numberOfRows(in tableView: NSTableView) -> Int {
return 10
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let id = tableColumn!.identifier
var view = tableView.makeView(withIdentifier: id, owner: nil) as? TableCellView
if view == nil {
view = TableCellView(id, itemCount: count)
}
count += 1
return view
}
}
class TableViewController: NSViewController {
private let tableViewDelegate = TableViewManager()
var scrollView: ScrollableTableView!
var tableView: NSTableView { get { return scrollView.tableView } }
// Initialize the table scroll view
convenience init(_ identifier: NSUserInterfaceItemIdentifier) {
self.init()
self.identifier = identifier
scrollView = ScrollableTableView(cols: [(500, "Commit")], delegate: tableViewDelegate, source: tableViewDelegate)
view = scrollView
tableView.rowSizeStyle = .custom
tableView.usesAutomaticRowHeights = true
tableView.rowHeight = 18
tableView.headerView = nil // Get rid of header
tableView.usesAlternatingRowBackgroundColors = true
}
// Pass along reload data
func reloadData() { tableView.reloadData() }
}
答案 0 :(得分:0)
最后想出了一个解决方案,但是我很想请一位真正的专家告诉我它是否强大。 (最多快速和肮脏的常数)。我重写了表格单元格绘制,对其初始化程序进行了一些修改,如下所示:
class TableCellView: NSTableCellView {
var title = NSTextField()
var height: NSLayoutConstraint!
convenience init(_ id: NSUserInterfaceItemIdentifier, itemCount: Int) {
self.init(frame: .zero)
identifier = id
rowSizeStyle = .custom
addSubview(title)
var s = "\(itemCount):\n"
for item in 0...(5 + itemCount) { s += "\(item)) Text written to a scrollable table view " }
let a = NSAttributedString(string: s, attributes: [NSAttributedString.Key.font : NSFont.systemFont(ofSize: 18.0)] )
title.attributedStringValue = a
title.textColor = NSColor.textColor
title.backgroundColor = NSColor.clear
title.translatesAutoresizingMaskIntoConstraints = false
title.isBordered = false
title.font = NSFont.systemFont(ofSize: 14.0)
title.widthAnchor.constraint(equalTo: widthAnchor, constant: 1).isActive = true
title.topAnchor.constraint(equalTo: topAnchor).isActive = true
title.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
height = heightAnchor.constraint(equalToConstant: 100) // Value doesn't matter, gets recalculated by override draw
height.isActive = true
}
override func draw(_ dirtyRect: NSRect) {
// Will recalculate height, but parameter must be larger than result
let bound = title.attributedStringValue.boundingRect(with: NSSize(width: frame.width, height: 4096), options: [.usesLineFragmentOrigin, .usesFontLeading])
height.constant = bound.height + 2.0
super.draw(dirtyRect)
}
}
并在调整窗口大小时正确重新包装。
希望这对其他人有帮助。