NSTableView не будет вызывать viewForTableColumn

Я пытаюсь создать табличное представление без построителя интерфейса с нуля в моем приложении Какао, и мой метод viewForTableColumn отказывается вызывать.

Мое табличное представление создано с использованием этого кода.

let tableView: NSTableView = {
    let table = NSTableView(frame: .zero)
    table.headerView = nil
    table.addTableColumn(NSTableColumn(identifier: .column))

    return table
}()

Еще у меня есть это расширение для класса NSUserInterfaceItemIdentifier

extension NSUserInterfaceItemIdentifier {
    static let cell = NSUserInterfaceItemIdentifier("cell")
    static let column = NSUserInterfaceItemIdentifier("column")
}

Мой контроллер представления реализует NSTableViewDataSource и NSTableViewDelegate, и они установлены в методе viewDidLoad. Табличное представление также находится в режиме прокрутки.

let scrollView = NSScrollView()

override func viewDidLoad() {
    self.scrollView.documentView = self.tableView
    self.scrollView.hasVerticalScroller = true
    self.view.addSubview(self.scrollView)

    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.reloadData() // To make sure the method would be called.
}

Значение, возвращаемое методом numberOfRows, больше 0 и выполняется.

Насколько я понимаю, следующий метод должен вызываться с параметром строки в диапазоне от 0 до значения, возвращаемого numberOfRows, но он никогда не вызывается.

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    guard let view = self.tableView.makeView(withIdentifier: .cell, owner: self) as? NSTableCellView else {
        return nil
    }

    // set the text/font for the view

    return view
}

Я также пробовал использовать dataCellFor и rowViewForRow, но ни один из них не вызывается.

РЕДАКТИРОВАТЬ:

Я проверил рамку своих элементов, чтобы убедиться, что вид таблицы и строки видны.

просмотреть иерархию


person afrigon    schedule 05.12.2018    source источник
comment
Невидимое табличное представление не требует представления. Какая рама у scrollView?   -  person Willeke    schedule 05.12.2018
comment
Рамка устанавливается по размеру окна, установка красного цвета фона подтверждает, что она видна.   -  person afrigon    schedule 05.12.2018
comment
Рамка представления таблицы и ширина столбца тоже в порядке? Если вы фиксируете иерархию представлений, отображается ли табличное представление?   -  person Willeke    schedule 05.12.2018
comment
Я добавил изображение иерархии представлений, синий вид - это scrollView, а красный - это tableView.   -  person afrigon    schedule 05.12.2018
comment
Я попробовал ваш код (добавил self.scrollView.frame = self.view.bounds и numberOfRowsInTableView) и называется viewForTableColumn. Возвращает nil.   -  person Willeke    schedule 05.12.2018
comment
Как вы думаете, в моей установке могло быть что-то внешнее? Код должен работать так, как вы упомянули. Это представление находится через секунду NSWindow, но, вероятно, все равно должно работать нормально.   -  person afrigon    schedule 05.12.2018
comment
Я ответил на аналогичный вопрос некоторое время назад - возможно, это поможет   -  person Paul Patterson    schedule 05.12.2018
comment
@PaulPatterson Ваш код очень похож на мой, не знаю, в чем причина моей проблемы.   -  person afrigon    schedule 05.12.2018


Ответы (1)


Согласно одному из комментариев под вашим вопросом, tableView(_:viewFor:row:) вызывается, он просто возвращает nil. Это имеет смысл, учитывая вашу реализацию этого метода. Когда makeViewWithIdentifier не работает, вам нужно вручную создать соответствующее представление и вернуть его, а не возвращать nil. Таким образом, ваша реализация должна выглядеть примерно так:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

    if let recycledView = self.tableView.makeView(withIdentifier: .cell, owner: self) as? NSTableCellView {
        return recycledView
    } else {
        // create view from scratch
        let newCell = NSTableCellView()
        newCell.identifier = NSUserInterfaceItemIdentifier.cell
        // customise here...
        return newCell
    }
}

Посмотрите еще раз на ссылку, которую я предоставил в своем комментарии, вы увидите, что эта реализация никогда не возвращает nil из этого метода.

person Paul Patterson    schedule 05.12.2018
comment
Я попытался поместить туда печать и точку останова, но ничего из этого не сработало. Я исправил свою проблему сейчас, но все еще не уверен, что было не так, я переписал весь NSWindow, с той лишь разницей, что я вынул NSViewController. Спасибо за Ваш ответ. - person afrigon; 06.12.2018