I'm stuck in a performance problem in my chat-like UITableview. I've got three types of cells:
- Text
- Image/video
- Audio
Currently I'm handling the dynamic cells height caching the size in a dictionary:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let estimatedHeight = self.estimatedMessagesHeights[indexPath] {
return estimatedHeight
}
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
self.estimatedMessagesHeights.updateValue(cell.bounds.size.height, forKey: indexPath)
}
It's not working very well, maybe scrolling is not that laggy but when I scroll to the bottom of the UITableView using
self.tblChat.scrollToRow(at: indexPath, at: .bottom, animated: false)
my app freeze for an instant. I tried setting a static height for the cells and the freeze is not happening.
In cellForRowAtIndexPath I dequeue the correct xib for the type of message, set the title label used for the "day" and the spacing from the previous message based on the date. After that I call the configuration method of the cell where I format and display the message text or I show the remote/local image using SDWebImage (after the download if necessary).
let message = self.model.getMessage(atIndex: indexPath.row)
var cell: ChatMessageTableViewCell?
if message.isSender {
if message.type == .audio {
cell = self.tblChat.dequeueReusableCell(withIdentifier: self.audioSenderIdentifier, for: indexPath) as! ChatAudioSenderTableViewCell
} else if message.type == .text {
cell = self.tblChat.dequeueReusableCell(withIdentifier: self.senderIdentifier, for: indexPath) as! ChatMessageSenderTableViewCell
} else {
cell = self.tblChat.dequeueReusableCell(withIdentifier: self.mediaSenderIdentifier, for: indexPath) as! ChatMediaSenderTableViewCell
}
} else {
if message.type == .audio {
cell = self.tblChat.dequeueReusableCell(withIdentifier: self.audioReceiverIdentifier, for: indexPath) as! ChatAudioReceiverTableViewCell
} else if message.type == .text {
cell = self.tblChat.dequeueReusableCell(withIdentifier: self.receiverIdentifier, for: indexPath) as! ChatMessageReceiverTableViewCell
} else {
cell = self.tblChat.dequeueReusableCell(withIdentifier: self.mediaReceiverIdentifier, for: indexPath) as! ChatMediaReceiverTableViewCell
}
}
let previousMessage = self.model.getMessage(atIndex: indexPath.row-1)
cell.topLabel.text = self.model.getMessageDayTitle(message: message, previousMessage: previousMessage)
cell.cntTopSpacing.constant = self.model.getSpacingBetweenMessages(previousMessage: previousMessage, message: message)
cell.configure(withMessage: message, chat: self.model.chat)
cell?.delegate = self
return cell
Any suggestions on how can I handle correctly the cells height calculation?