我在MacOSX应用程序中有一个基于视图的NSTableView,可以很好地构建数据。我想实现NSTableView的行高,它随着输入NSTextViews之一的数据内容而增长。我已经将NSTextView子类化为" grow"使用用户文本,但问题是嵌入TableView中的字段会导致字段被剪裁。
有没有人对如何实现不断增长的行大小有任何建议?
答案 0 :(得分:7)
您需要在表视图委托中实现-tableView:heightOfRow:
并返回该行的适当高度。此外,您需要监视文本视图的高度变化,并在表视图中的任何更改时调用-noteHeightOfRowsWithIndexesChanged:
。要监控文本视图的高度,只需观察他们将发布的NSViewFrameDidChangeNotification
即可。
(如果您在UI中通常使用自动布局,我认为您必须将文本视图保留为translatesAutoresizingMaskIntoConstraints
,手动放置它们,并根据需要设置自动调整遮罩。然后,您将避免对它们设置任何其他约束。这是因为您需要框架由文本布局管理器设置,而不是通过自动布局设置。)
答案 1 :(得分:1)
我已经设法在Swift 3中实现了这一点(在this提示和this以及this SO答案的帮助下):
确保NSTableView
中的表格视图单元格与您的子类/视图控制器的委托连接采用NSTextFieldDelegate
协议。
还要给它这些约束,以确保它根据行的高度调整大小:
在委托中使用此代码:
var editedString: String? = nil
var textCellForHeight: NSTextFieldCell = NSTextFieldCell.init()
func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {
editedString = fieldEditor.string ?? ""
return true
}
func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
editedString = nil
return true
}
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
if commandSelector == #selector(insertNewline(_:)) {
textView.insertNewlineIgnoringFieldEditor(self)
editedString = textView.string ?? ""
//The NSAnimationContext lines get rid of the animation that normally happens when the height changes
NSAnimationContext.beginGrouping()
NSAnimationContext.current().duration = 0
myTableView.noteHeightOfRows(withIndexesChanged: IndexSet.init(integer: selected))
NSAnimationContext.endGrouping()
myTable.needsDisplay = true
return true
}
return false
}
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
if let temp = editedString { //we know it’s currently being edited if it’s not nil
textCellForHeight.stringValue = temp
//in my case, there was a specific table column that I knew would be edited
//you might need to decide on the column width another way.
let column = myTable.tableColumns[myTable.column(withIdentifier: “TheColumnThatsBeingEdited”)]
let frame: NSRect = NSMakeRect(0, 0, column.width, CGFloat.greatestFiniteMagnitude)
return textCellForHeight.cellSize(forBounds: frame).height
}
return yourStandardHeightCGFloat
}