My UITableView
cells for a messaging ViewController
only get the right height dimension when I scroll up or down the tableview and sometimes when I send a new message. I have seen most people solve this with cell.layoutIfNeeded
but for me, it does not work. Any ideas why?
automaticDimension and cell.layoutIfNeeded:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
messageTableView.estimatedRowHeight = 120.0
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customMessageCell", for: indexPath) as! CustomMessageCell
cell.ourMessageBackground.backgroundColor = UIColor(displayP3Red: 59/255.0, green: 89/255.0, blue: 152/255.0, alpha: 1)
cell.ourMessageBody.textColor = UIColor.white
cell.avatarImageView.backgroundColor = UIColor(white: 0.95, alpha: 1)
cell.messageBackground.backgroundColor = UIColor(white: 0.95, alpha: 1)
cell.layoutIfNeeded() //<-- Layout if needed
return cell
}
Code for setting up the cell:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? CustomMessageCell else { return }
//Sets cell to message
let senderId = messageArray[indexPath.row].fromId
if senderId == Auth.auth().currentUser?.uid as String? {
//Messages We Sent
cell.ourMessageBody.text = messageArray[indexPath.row].messageBody
cell.avatarImageView.isHidden = true
cell.messageBackground.isHidden = true
cell.ourMessageBackground.isHidden = false
} else {
//Messages someone else sent
cell.messageBody.text = messageArray[indexPath.row].messageBody
cell.avatarImageView.isHidden = false
cell.messageBackground.isHidden = false
cell.ourMessageBackground.isHidden = true
cell.layoutIfNeeded()
//toId ProfileImage
if let imageID = toId {
let imagesStorageRef = Storage.storage().reference().child("profilepic/").child(imageID)
imagesStorageRef.getData(maxSize: 1*1024*1024, completion: { (data, error) in
if error != nil{
print(error)
return
}
DispatchQueue.main.async {
guard let c = tableView.cellForRow(at: indexPath) else { return }
cell.avatarImageView?.image = UIImage(data: data!)
}
})
}
}
}
Code for retrieving messages from Firebase:
func retrieveMessages() {
SwipingView.myAdvertiserVar()
let testUserOrAd = SwipingView.myAdvertiserVar.advertiser
if testUserOrAd == true{
if let testId = self.toId{
let MessageDB = Database.database().reference().child("Users").child(toId!).child("Messages").child(uid!)
MessageDB.observe(.childAdded) { (snapshot) in
let snapshotValue = snapshot.value as? [String: AnyObject]
let text = snapshotValue!["MessageBody"] as? String
let fromId = snapshotValue!["FromId"] as? String
let time = snapshotValue!["TimeStamp"] as? Int
let message = Message()
message.messageBody = text
message.fromId = fromId
self.user.timeStamp = time
self.messageArray.append(message)
self.messageTableView.reloadData()
self.messageTableView.scrollToRow(at: IndexPath(row: self.messageArray.count-1, section: 0), at: .bottom, animated: false)
}
}
}
}
Constraints, the descendant is for the label itself, the other is the background:
This is the outcome when i type a long text, it gets cut instead of the height adjusted to the content:
When i type the same exact text again and click send i get the desired outcome for the latest text only:
Why do you put both
messageTableView.estimatedRowHeight = 120.0 return UITableView.automaticDimension
inside your tableView(_ tableView:, estimatedHeightForRowAt indexPath:) method? It does not make sense to do so, use estimatedHeight to help tableView out in creating your cell. As a result, just return a CGFloat will do the job i.e
}
To add AutomaticDimension for your cell. Add this: