Как исправить ошибку «невозможно удалить ячейку» в Swift - PullRequest
0 голосов
/ 20 апреля 2019

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

У меня есть два представления таблицы в одном контроллере представления, и они оба прекрасно работают, переключаясь назад и вперед,но только если один из них загружается первым.

Когда я сначала пытаюсь загрузить другую (что я иногда хочу сделать в зависимости от пути пользователя к таблице), приложение вылетает с ошибкой «невозможно вывести ячейку из очереди с идентификатором customMessageCell -необходимо зарегистрировать перо или класс для идентификатора или подключить ячейку прототипа в раскадровке "

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

В моем viewDidLoad:

messageTableView.register(UINib(nibName: "CustomMessageCell", bundle: nil), forCellReuseIdentifier: "customMessageCell")
listTableView.register(UINib(nibName: "ItemCell", bundle: nil), forCellReuseIdentifier: "itemCell")

Кроме того, у меня есть перечисление, которое переключает таблицы

switch currentTable {
case .list:
   tableSelected(table: "list")
case .notes:
   tableSelected(table: "notes")
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        switch currentTable {
        case .list:
            let cell = tableView.createCell(tableView: listTableView, indexPath: indexPath, itemArray: listArray)
            return cell
        case .notes:
            let cell = tableView.dequeueReusableCell(withIdentifier: "customMessageCell", for: indexPath) as! CustomMessageCell

            if messageArray.count == 0 {
                cell.messageBody.text = "No notes yet"
            } else {
                cell.messageBody.text = messageArray[indexPath.row].messageBody
                cell.senderUser.text = messageArray[indexPath.row].sender

                let user = cell.senderUser.text

                switch user {
                case "jeffrey@sandiegomentors.com":
                    cell.avatarImageView.image = UIImage(named: "team-4")
                case "djones219@pointloma.edu":
                    cell.avatarImageView.image = UIImage(named: "team-3")
                case "dave@sandiegomentors.com":
                    cell.avatarImageView.image = UIImage(named: "team-2")
                case "amirthought@gmail.com":
                    cell.avatarImageView.image = UIImage(named: "team-6")
                case "james@sandiegomentors.com":
                    cell.avatarImageView.image = UIImage(named: "team-1")
                default:
                    cell.avatarImageView.image = UIImage(named: "twitteregg")
                }

                if cell.senderUser.text == Auth.auth().currentUser?.email as String? {
                    cell.messageBackground.backgroundColor = #colorLiteral(red: 0.005996327382, green: 0.4056355059, blue: 0.8481400013, alpha: 1)
                } else {
                    cell.messageBackground.backgroundColor = #colorLiteral(red: 0.3254587054, green: 0.325510323, blue: 0.3254474401, alpha: 1)
                }

                if let timeStamp = messageArray[indexPath.row].time {
                    let date = Date(timeIntervalSince1970: timeStamp/1000)
                    let formatter = DateFormatter()
                    formatter.dateFormat = "MMM d, yyyy"
                    let dateString = formatter.string(from: date)
                    cell.timeLabel.text = dateString
                }
            }

            return cell
        }
func tableSelected(table: String) {
        if table == "list" {
            listTableView.isHidden = false
            messageTableView.isHidden = true
            messageInputView.isHidden = true
            addButton.isEnabled = true

            currentTable = .list

            buttonSelection(selected: tabButtons[1], unselected: tabButtons[0])

            buttonTodoWidthConstraint.isActive = true
            buttonNotesWidthConstraint.isActive = false

            listTableView.reloadData()

        } else {

            messageTableView.isHidden = false
            messageInputView.isHidden = false
            listTableView.isHidden = true
            addButton.isEnabled = false

            currentTable = .notes

            buttonSelection(selected: tabButtons[0], unselected: tabButtons[1])

            buttonNotesWidthConstraint.isActive = true
            buttonTodoWidthConstraint.isActive = false

            messageTableView.reloadData()
            scrollToBottom()
        }
    }

Когда я запускаю приложение и имею начальную currentTable как .list, я могу переключаться между ними (с помощью кнопки, которая переключает значение enum), и она работает как положено.

Когда у меня естьначальная currentTable как .notes, он сразу падает.

Есть идеи?

Заранее спасибо

1 Ответ

0 голосов
/ 20 апреля 2019

Если вы получаете сообщение об ошибке «невозможно удалить из очереди ячейку», даже если в каждой таблице зарегистрирован соответствующий идентификатор ячейки, это означает, что вы, вероятно, создали экземпляр ячейки для одной таблицы, когда cellFor был вызван для другой.Это легко сделать, если у вас есть один набор UITableViewDataSource методов, обслуживающих обе таблицы.Вы можете подтвердить это, добавив точку останова в cellFor, сравните tableView, переданный этому методу, с вашими двумя выходами для messageTableView и listTableView: убедитесь, что вы создаете экземпляр ячейки, подходящей для этой таблицы.

Вместо того, чтобы cellFor полагаться на currentTable, я бы предложил просто проверить tableView, чтобы определить, какой тип ячейки должен быть создан.Тогда невозможно вообще создать иную ошибочную ячейку.Вы, возможно, даже можете полностью исключить currentTable.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    switch tableView {
    case messageTableView:
        ...

    case listTableView:
        ...

    default:
        fatalError()
    }
}

Честно говоря, я бы не рекомендовал использовать один UITableViewDataSource для двух разных таблиц.Альтернативой является инкапсуляция UITableViewDataSource для каждого в свой собственный объект, и это снова делает невозможным создание неправильной ячейки для данной таблицы.Это также помогает уменьшить раздувание контроллера представления.

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