Выберите ячейку таблицы программно в Swift - PullRequest
0 голосов
/ 20 марта 2020

В Swift я могу выбрать ячейку таблицы следующим образом:

 let indexPath = IndexPath(row: 0, section: 0);
 tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)

Но пытаюсь вызвать didSelectRowAt следующим образом:

tableView.delegate?.tableView!(tableView, didSelectRowAt: indexPath)

Что вызывает это:

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = categoryListView.cellForRow(at: indexPath) as! CategoryCellView   // error here

    //do other stuff
}

и вызывает эту ошибку на //error here выше: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Я использую этот класс для CategoryCellView, который является отдельным пером:

@IBDesignable
class CategoryCellView: UITableViewCell {
    @IBOutlet weak var myCategoryView: Category!
    var categoryId: Int?
    var index: Int?
}

Как я могу вызвать didSelectRowAt здесь?

Ответы [ 2 ]

1 голос
/ 20 марта 2020

cellForRow(at: indexPath) может вернуть nil, если ячейка не видна - и ячейка может быть не видна сразу после вызова selectRow. Поэтому я бы рекомендовал обновить реализацию didSelectRow, чтобы избежать принудительного развертывания as! и быть более оборонительным:

if let cell = categoryListView.cellForRow(at: indexPath) as? CategoryCellView {
    // do stuff with the cell
}

(или, возможно, использовать guard let, если это имеет больше смысла)

Я бы рекомендовал , а не , непосредственно вызывая функции UITableView или UITableViewDelegate, такие как didSelectRow (или другие стандартные функции делегата UIKit), из вашего собственного кода, поскольку это нарушает первоначальный контракт на разработку этих функций. Это может привести к ошибкам или нежелательному поведению, если вы вызываете didSelectRow непосредственно для объекта UITableView. Вместо этого напишите другую пользовательскую функцию в вашем классе, которая реализует UITableViewDelegate, где вы можете обновить соответствующий UITableViewCell после вызова selectRow. Вы могли бы вызвать эту же функцию из вашей реализации didSelectRow и, таким образом, повторно использовать некоторый код.

В зависимости от того, что вам нужно сделать с ячейкой в ​​вашем методе didSelectRow, вы можете обратиться к сценарию программной c -выборки в другие способы. Например:

  • В вашей реализации cellForRowAt вы можете проверить, является ли indexPath == tableView.indexPathForSelectedRow или tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false, чтобы определить, является ли ячейка, которая должна быть отображена, выбранной. Обратите внимание, что в этот момент значение ячейки isSelected может быть ложным. UITableView установит isSelected в true, если необходимо сразу после этого. Что приводит ко второму варианту:
  • Реализация override func setSelected(_ selected: Bool, animated: Bool) в вашем CategoryCellView, если вам просто нужно обновить внешний вид этой указанной c ячейки табличного представления. Если ячейка уже видна при вызове selectRow, setSelected будет вызвано немедленно. Если ячейка не видна во время вызова selectRow, setSelected будет вызываться в этой ячейке позже, сразу после вызова делегата tableView(_:,cellForRowAt:), когда пользователь прокручивает до этой ячейки
0 голосов
/ 20 марта 2020

Ты близко ...

Дай попробовать:

    let indexPath = IndexPath(row: 0, section: 0);
    tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    self.tableView(tableView, didSelectRowAt: indexPath)


Редактировать

Как уже отмечалось (и это можно найти во многих местах), никогда не следует вызывать методы делегата, содержащие will, did и should самостоятельно.

Другой подход может быть:

@objc func simulateSelectRow() -> Void {
    print("sim")
    let indexPath = IndexPath(row: 0, section: 0);
    tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    myDidSelectRowAt(tableView, indexPath: indexPath)
}

func myDidSelectRowAt(_ tableView: UITableView, indexPath: IndexPath) -> Void {
    // do what you want when row is selected
    print("Row:", indexPath.row, "in Section:", indexPath.section, "was selected.")
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    myDidSelectRowAt(tableView, indexPath: indexPath)
}

Это может или не может подходить для ваших нужд - но это может быть вариант.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...