У меня самая странная проблема с моим NSOutlineView
:
- Все настроено в раскадровке, то есть в виде контура и двух
NSTableCellView
s - Два вида ячеек в основном одинаковы, только один показывает значок, другой - нет
- Я могу начать редактирование элемента (строки), нажав клавишу
Return
, то есть NSTextField
, которая часть моего NSTableCellView
входит в режим редактирования. Это поведение по умолчанию и до сих пор работает отлично.
Однако:
- После того, как редактирование заканчивается и элемент был изменен, я использую вторую ячейку табличного представления из раскадровки (тот, у которого нет значка).
- Теперь переход в режим редактирования нажатием клавиши
Return
больше не работает! Приложение подает звуковой сигнал и все.
Оба вида ячеек по отдельности доступны для редактирования при первоначальной загрузке. Я подтвердил это. Проблема возникает, когда элемент сначала отображается с одним представлением ячейки таблицы, а затем с другим (и наоборот).
Редактирование элемента несколько раз работает нормально, тогда базовый NSTableCellView
не меняется. Кто-нибудь может пролить свет на то, что здесь происходит?
Воспроизвести:
- Новый проект Xcode, Ma c app
- Добавьте
NSOutlineView
к вашему контроллеру представления с одним столбцом - Добавьте две ячейки табличного представления, "Один", "Два" (идентификаторы)
- Используйте код ниже
Шаги:
- Запустите приложение, выберите второй элемент
- Нажмите «Возврат», введите «зеленый», «Возврат»
- Нажмите «Return» еще раз, чтобы войти в режим редактирования во второй раз
Ожидается:
- Ячейка должна снова стать редактируемой
Фактически:
- Приложение подает звуковые сигналы
Код:
import Cocoa
class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate, NSTextFieldDelegate {
@IBOutlet var outlineView: NSOutlineView!
private var items = ["One", "Two"]
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
return item == nil ? items.count : 0
}
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
return items[index]
}
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
return false
}
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
guard let item = item as? String else { return nil }
NSLog("Vending cell view for: \(item)")
let identifier = item.contains("green") ? "Two" : "One"
if let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: identifier), owner: nil) as? NSTableCellView
{
view.textField?.stringValue = item
view.textField?.delegate = self
return view
}
return nil
}
func controlTextDidEndEditing(_ obj: Notification) {
NSLog("Did end editing")
guard
let textField = obj.object as? NSTextField,
let item = outlineView.item(atRow: outlineView.row(for: textField)) as? String else {
return
}
NSLog("Reloading item: \(item)")
let row = outlineView.row(for: textField)
items[row] = textField.stringValue
outlineView.reloadItem(item)
}
}
ОБНОВЛЕНИЕ:
Я нашел обходной путь, но для меня это выглядит как ошибка. Если я позвоню outlineView.reloadData(forRowIndexes:columnIndexes:)
сразу после reloadItem()
, проблема не возникнет.
Не работает (проблема возникает):
outlineView.reloadItem(item)
Не работает (модель данных outlineView не обновлена, отображается старое значение):
outlineView.reloadData(forRowIndexes: IndexSet([row]), columnIndexes: IndexSet([0]))
Это наконец-то работает:
outlineView.reloadItem(item)
outlineView.reloadData(forRowIndexes: IndexSet([row]), columnIndexes: IndexSet([0]))
Приведенное выше действие вызывает запрос на просмотр ячейки во второй раз.