2014-10-11 113 views
3

我有一个基于视图的NSTableView在MacOSX应用程序中很好地构建数据。我希望实现NSTableView具有与输入到NSTextView之一中的数据内容一起增长的行高。我已经使用用户文本将NSTextView分类为“增长”,但问题是将TableView嵌入到TableView中会导致字段被剪辑。越来越多的NSTableView行高度

有没有人有任何建议如何去实施增长的行大小?

回答

4

您需要在您的表视图委托中实现-tableView:heightOfRow:并返回该行的相应高度。此外,您需要监视文本视图以了解其高度变化,并在任何变化时在表格视图上调用-noteHeightOfRowsWithIndexesChanged:。要监视文本视图的高度,只需观察NSViewFrameDidChangeNotification即可发布。 (如果您在UI中通常使用自动布局,我认为您必须将文本视图保存为translatesAutoresizingMaskIntoConstraints,然后手动放置它们,并根据需要设置其自动识别遮罩,然后避免设置任何这是因为你需要通过文本布局管理器设置框架,但不是通过自动布局设置。)

+0

感谢县,这是一个巨大帮帮我。我已经实现了-tableView:heightOfRow:但是我在监视文本视图时遇到了麻烦。在IB中使用autoLayout功能给了我后来扩展的textView(感谢那个 - 比我原来更清洁的解决方案),但是我仍然在监视文本视图方面存在问题。你可以详细说一下使用noteHeighOfRowsWithIndexesChanged:和NSViewFrameDidChangeNotification吗? – user3932488 2014-10-12 06:43:08

+0

什么方面给你带来麻烦?每次向表中添加文本视图时,都会将控制器对象作为'NSViewFrameDidChangeNotification'的观察者添加到'[NSNotificationCenter defaultCenter]',并在发送“object”处显示文本视图。然后,在你的通知处理代码中,你使用' - [NSTableView rowForView:]'来查找哪个行对应于其帧改变的视图(通知的'object')。然后你在表视图上调用'-noteHeightOfRowsWithIndexesChanged:',传递一个包含行索引的索引集。当你移除视图时停止观察。 – 2014-10-12 07:16:22

+0

好吧,我不认为我正确理解这一点。我实现了-noteHeightofRowsWithIndexesChanged:但它似乎没有被调用。我需要在我的AppDelegate中初始化NSNotificationCentre吗? – user3932488 2014-10-12 07:50:45

0

我已经设法在Swift 3中实现了这个(在this的帮助下, thisthis 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 
}