2014-10-11 110 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 
}