Строка NSOutlineView больше не редактируется клавишей «Return» после перезагрузки другой ячейки табличного представления - PullRequest
1 голос
/ 25 февраля 2020

У меня самая странная проблема с моим NSOutlineView:

  • Все настроено в раскадровке, то есть в виде контура и двух NSTableCellView s
  • Два вида ячеек в основном одинаковы, только один показывает значок, другой - нет
  • Я могу начать редактирование элемента (строки), нажав клавишу Return, то есть NSTextField, которая часть моего NSTableCellView входит в режим редактирования. Это поведение по умолчанию и до сих пор работает отлично.

Однако:

  • После того, как редактирование заканчивается и элемент был изменен, я использую вторую ячейку табличного представления из раскадровки (тот, у которого нет значка).
  • Теперь переход в режим редактирования нажатием клавиши Return больше не работает! Приложение подает звуковой сигнал и все.

Оба вида ячеек по отдельности доступны для редактирования при первоначальной загрузке. Я подтвердил это. Проблема возникает, когда элемент сначала отображается с одним представлением ячейки таблицы, а затем с другим (и наоборот).

Редактирование элемента несколько раз работает нормально, тогда базовый NSTableCellView не меняется. Кто-нибудь может пролить свет на то, что здесь происходит?

Воспроизвести:

  1. Новый проект Xcode, Ma c app
  2. Добавьте NSOutlineView к вашему контроллеру представления с одним столбцом
  3. Добавьте две ячейки табличного представления, "Один", "Два" (идентификаторы)
  4. Используйте код ниже

Шаги:

  1. Запустите приложение, выберите второй элемент
  2. Нажмите «Возврат», введите «зеленый», «Возврат»
  3. Нажмите «Return» еще раз, чтобы войти в режим редактирования во второй раз

Ожидается:

  • Ячейка должна снова стать редактируемой

Фактически:

  • Приложение подает звуковые сигналы

NSOutlineView

Код:

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]))

Приведенное выше действие вызывает запрос на просмотр ячейки во второй раз.

...