2014-10-11 2 views
3

У меня есть NSTableView на основе представления в приложении MacOSX, которое прекрасно структурирует данные. Я хотел бы реализовать NSTableView, чтобы иметь высоту строк, которые растут с содержимым данных, введенных в один из NSTextViews. Я подклассифицировал NSTextView, чтобы «расти» с текстом пользователя, но проблема в том, что наличие поля, встроенного в TableView, вызывает обрезание поля.Рост высоты строки NSTableView

Есть ли у кого-нибудь какие-либо предложения относительно того, как идти о внедрении растущего размера строки?

ответ

4

Вам необходимо реализовать -tableView:heightOfRow: в вашем делегате представления таблицы и вернуть соответствующую высоту для строки. Кроме того, вам нужно отслеживать текстовые представления для изменения их высоты и вызывать -noteHeightOfRowsWithIndexesChanged: в представлении таблицы, когда какое-либо из них изменяется. Чтобы контролировать высоту текстовых просмотров, достаточно заметить, что они отправят сообщение NSViewFrameDidChangeNotification.

(Если вы используете автоматическую компоновку, как правило, в своем пользовательском интерфейсе, я думаю, вам придется оставить текстовые представления с помощью translatesAutoresizingMaskIntoConstraints, поместить их вручную и, при необходимости, установить маски авторезистирования. другие ограничения на них. Это связано с тем, что вам нужен фрейм, который должен быть установлен менеджером компоновки текста, но не с помощью автоматического макета.)

+0

Благодаря кен, это огромный Помогите. Я реализовал -tableView: heightOfRow: но у меня возникают проблемы с мониторингом текстовых просмотров. Игра с функциями autoLayout в IB дала мне расширяющийся текст, который я получил после (спасибо за это - гораздо более чистое решение, чем я изначально), но у меня проблемы с просмотром текстового представления. Можете ли вы подробнее рассказать об использовании noteHeighOfRowsWithIndexesChanged: и NSViewFrameDidChangeNotification? – user3932488

+0

Какой аспект дает вам проблемы? Каждый раз, когда вы добавляете текстовый вид в таблицу, вы добавляете свой объект контроллера в качестве наблюдателя 'NSViewFrameDidChangeNotification' в' [NSNotificationCenter defaultCenter] 'с текстовым представлением объекта публикации. Затем в вашем коде обработки уведомлений вы просматриваете, какая строка соответствует представлению, чей фрейм изменился («объект» уведомления), используя '- [NSTableView rowForView:]'. Затем вы вызываете '-noteHeightOfRowsWithIndexesChanged:' в представлении таблицы, передавая индексный набор, содержащий индекс строки. Прекратите наблюдать, когда вы удаляете представление. –

+0

Хорошо, я не думаю, что понимаю это правильно. Я реализовал -noteHeightofRowsWithIndexesChanged: но похоже, что он не вызван. Нужно ли инициализировать NSNotificationCentre в моем AppDelegate? – user3932488

0

Мне удалось реализовать это в 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 
} 
Смежные вопросы