不断增长的NSTableView行高

时间:2014-10-11 22:24:27

标签: macos cocoa nstableview nstextview

我在MacOSX应用程序中有一个基于视图的NSTableView,可以很好地构建数据。我想实现NSTableView的行高,它随着输入NSTextViews之一的数据内容而增长。我已经将NSTextView子类化为" grow"使用用户文本,但问题是嵌入TableView中的字段会导致字段被剪裁。

有没有人对如何实现不断增长的行大小有任何建议?

2 个答案:

答案 0 :(得分:7)

您需要在表视图委托中实现-tableView:heightOfRow:并返回该行的适当高度。此外,您需要监视文本视图的高度变化,并在表视图中的任何更改时调用-noteHeightOfRowsWithIndexesChanged:。要监控文本视图的高度,只需观察他们将发布的NSViewFrameDidChangeNotification即可。

(如果您在UI中通常使用自动布局,我认为您必须将文本视图保留为translatesAutoresizingMaskIntoConstraints,手动放置它们,并根据需要设置自动调整遮罩。然后,您将避免对它们设置任何其他约束。这是因为您需要框架由文本布局管理器设置,而不是通过自动布局设置。)

答案 1 :(得分:1)

我已经设法在Swift 3中实现了这一点(在this提示和this以及this SO答案的帮助下):

enter image description here

确保NSTableView中的表格视图单元格与您的子类/视图控制器的委托连接采用NSTextFieldDelegate协议。

还要给它这些约束,以确保它根据行的高度调整大小:

enter image description here

在委托中使用此代码:

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
}