Представления содержимого не отображаются на UITableViewCell

Это часть моей раскадровки:

Образ

это мое работающее приложение:

Образ

Это моя часть кодов:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 0 {
            if indexPath.row == 0 {
                 return super.tableView(tableView, cellForRowAt: indexPath)
            } else {
                tableView.register(SubTextFieldCell.self, forCellReuseIdentifier: "SubTextFieldCell")
                let cell = tableView.dequeueReusableCell(withIdentifier: "SubTextFieldCell", for: indexPath) as! SubTextFieldCell

//                cell.deleteButton.isEnabled = true
//                cell.subTextfield.text = "OK"

                print("indexPath.row: \(indexPath.row)")

                return cell
            }
...

Я уже подключил кнопку и текстовое поле в разных местах, и я могу гарантировать, что эта часть не ошибается, но когда я нажимаю кнопку "Добавить" в первой строке, я получаю только ячейку без какого-либо содержимого.

Если я использую такой код cell.deleteButton...Xcode сообщит об ошибке:

Поток 1: фатальная ошибка: неожиданно обнаружен ноль при развертывании необязательного значения

Затем я попытался использовать viewWithTag метод, чтобы увидеть, если показать содержимое, но я все еще получаю ту же ошибку, что и раньше.

Это первый раз, когда я столкнулся с такой ошибкой. У меня нет ошибок с аналогичным кодом и методами в других моих программах.

1 ответ

Когда вы настраиваете пользовательские ячейки внутри файла раскадровки, вам не нужно вызывать register(_:forCellReuseIdentifier:) потому что раскадровка должна была сделать это для вас.

Причина deleteButton это ноль, потому что, перерегистрируя класс ячейки, как вы это сделали, вы перезаписали то, что раскадровка зарегистрировала для вас. Все ячейки, созданные путем удаления из очереди с этим идентификатором повторного использования, не будут иметь никакого отношения к раскадровке и будут просто пустыми.

Предполагая все @IBOutlets и идентификаторы повторного использования и все настраивается (что вы сказали, что сделали), затем просто удалите ячейку из очереди с идентификатором повторного использования, установленным в раскадровке.

Пример ячейки dequeue:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section == 0 {
        if indexPath.row == 0 {
            return super.tableView(tableView, cellForRowAt: indexPath)
        } else {
            // Registering again is unnecessary, because the storyboard should have already done that.
//            tableView.register(SubTextFieldCell.self, forCellReuseIdentifier: "SubTextFieldCell")
            let cell = tableView.dequeueReusableCell(withIdentifier: "SubTextFieldCell") as! SubTextFieldCell

            cell.deleteButton.isEnabled = true
            cell.subTextfield.text = "OK"

            return cell
        }
    } else {
        ...
    }
}

Замечания:

Даже в тех случаях, когда вам нужно зарегистрировать класс в табличном представлении, вам нужно будет сделать это только один раз. (Например, во время viewDidLoad)

Даже в те времена, вы не должны называть это каждый раз, когда вы удаляете ячейку. Вы просто заставляете свое приложение работать тяжелее.

Подключение представлений к ячейкам в раскадровке

Установите подкласс для табличного представления Подкласс установлен в табличное представление в раскадровке

Установите подкласс для первой ячейки прототипа Подкласс установлен в прототип ячейки

Установить идентификатор повторного использования для ячейки прототипа

Обязательно подпишите (UIButtonи т. д.) связан с собственностью @IBOutlet (код подкласса показан ниже) IB Outlet установлен на кнопку, как видно по ячейке IB Outlet установлен на кнопку, как видно по кнопке

пример UITableViewController подкласс:

class MyTableViewController: UITableViewController {

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "MyFirstCell", for: indexPath) as! MyFirstTableViewCell

            // Configure cell if needed
            cell.myButton.setTitle("New Button Text", for: .normal)
            cell.myButton.tintColor = .green

            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "MySecondCell", for: indexPath) as! MySecondTableViewCell

            // Configure cell if needed
            cell.myTextField.backgroundColor = .red

            return cell
        }
    }

}

пример UITableViewCell подкласс:

class MyFirstTableViewCell: UITableViewCell {

    @IBOutlet weak var myButton: UIButton!

}

Результат:

Снимок экрана симулятора, показывающий изменения в подпредставлениях ячеек

Другие вопросы по тегам