В настоящее время я создаю приложение чата для клиента.
Чат реализован с использованием UITableView с пользовательскими ячейками.
Текстовое сообщение от бота строится как пользовательский UITableViewCell с UITextView (потому что он должен быть кликабельным для ссылок, в противном случае я бы использовал UILabel), обернутым внутри контейнера UIView, чтобы нарисовать пузырь вокруг него. Также этот вид контейнера имеет тень, чтобы понравиться дизайнеру: P
Каждый раз при получении нового сообщения от бота это сообщение задерживается на долю времени, чтобы пользователь мог прочитать сообщение раньше. В это время так называемый WaitingMessageTableViewCell отображается в индексе, в который будет поступать новая ячейка. По истечении времени WaitingMessageTableViewCell удаляется из модели, а затем из tableView и вставляется новая ячейка.
tableView.beginUpdates()
if let insertRows = insertRows {
tableView.insertRows(at: insertRows, with: .none)
}
if let deleteRows = deleteRows {
tableView.deleteRows(at: deleteRows, with: .none)
}
if let reloadRows = reloadRows {
tableView.reloadRows(at: reloadRows, with: .none)
}
tableView.endUpdates()
Проблема была найдена дизайнером, который сказал, что когда WaitingMessageTableViewCell собирается появиться, тень ячейки до того, как становится сильнее в течение некоторого времени. Я отладил в нем и обнаружил, что перед вставкой WaitingMessageTableViewCell он появляется за ячейкой, что для меня не имеет смысла (это механизм повторного использования ?!)
Теперь самое странное: я использовал встроенный в Xcode UI Analyzer и увидел, что за видимыми ячейками есть скрытые ячейки, которые не представлены моделями.
(lldb) po tableView.subviews
▿ 5 elements
▿ 0 : <CHAT.WaitingMessageTableViewCell: 0x7fdef286a600; baseClass = UITableViewCell; frame = (0 395.5; 375 40); hidden = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x600003952d80>>
▿ 1 : <CHAT.AgentMessageTableViewCell: 0x7fdef2861e00; baseClass = UITableViewCell; frame = (0 294.5; 375 101); hidden = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x6000039bf160>>
▿ 2 : <CHAT.AgentMessageTableViewCell: 0x7fdef3897600; baseClass = UITableViewCell; frame = (0 395.5; 375 101.5); opaque = NO; autoresize = W; layer = <CALayer: 0x6000039aba20>>
▿ 3 : <CHAT.AgentMessageTableViewCell: 0x7fdef382e200; baseClass = UITableViewCell; frame = (0 294.5; 375 101); opaque = NO; autoresize = W; layer = <CALayer: 0x600003955a00>>
▿ 4 : <CHAT.WelcomeTableViewCell: 0x7fdef2882c00; baseClass = UITableViewCell; frame = (0 0; 375 294.5); clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x600003951160>>
(lldb) po tableView.visibleCells
▿ 3 elements
▿ 0 : <CHAT.WelcomeTableViewCell: 0x7fdef2882c00; baseClass = UITableViewCell; frame = (0 0; 375 294.5); clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x600003951160>>
▿ 1 : <CHAT.AgentMessageTableViewCell: 0x7fdef382e200; baseClass = UITableViewCell; frame = (0 294.5; 375 101); opaque = NO; autoresize = W; layer = <CALayer: 0x600003955a00>>
▿ 2 : <CHAT.AgentMessageTableViewCell: 0x7fdef3897600; baseClass = UITableViewCell; frame = (0 395.5; 375 101.5); opaque = NO; autoresize = W; layer = <CALayer: 0x6000039aba20>>
(lldb) po AssistantDataManager.shared.cellModels
▿ 3 elements
▿ 0 : <WelcomeCellModel: 0x600002c80740>
▿ 1 : <SimpleAgentTextCellModel: 0x600001af0050>
▿ 2 : <AskQuestionCellModel: 0x600002c80400>
Также вот мой метод cellForRows:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard indexPath.row < AssistantDataManager.shared.cellModels.count else {
return UITableViewCell()
}
let cellModel = AssistantDataManager.shared.cellModels[indexPath.row]
if let cell = tableView.dequeueReusableCell(withIdentifier: cellModel.cellReuseIdentifier) as? AssistantActionBaseTableViewCell {
//Quickfix for stronger shadow
cell.backgroundColor = Colors.tableViewBackgroundColor
cell.configure(with: cellModel)
if let topContraint = cell.topContraint {
topContraint.constant = calculateTopContraintSpacing(for: indexPath)
}
if let bottomContraint = cell.bottomContraint {
bottomContraint.constant = 0
}
cell.selectionStyle = .none
return cell
}
return UITableViewCell()
}
Кто-нибудь может мне сказать, почему новый вставленный WaitingMessageTableViewCell сначала находится за ячейкой выше, а затем перемещается вниз, и почему мой tableView заполняется гораздо большим количеством ячеек, чем должно быть?
Большое спасибо заранее.