I am attempting to size the height of the UICollectionViewCell according to the height of the text. For some odd reason, the height of the text is extremely gibberish. I adopted various solutions in the posts here, here and here but all somehow did not work in my case.
My approach involves autolayout which I do not think is a contributing factor. My code so far:
class ChatBubbleCollectionViewCell: UICollectionViewCell {
let textView: UITextView = {
let tv = UITextView()
tv.translatesAutoresizingMaskIntoConstraints = false
tv.backgroundColor = .lightGray
tv.font = UIFont.systemFont(ofSize: 17)
tv.isScrollEnabled = false
tv.isEditable = false
tv.sizeToFit()
tv.contentInset.top = -4
return tv
}()
let bubbleView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.layer.cornerRadius = 8
return v
}()
var bubbleWidthAnchor: NSLayoutConstraint!
var bubbleLeftAnchor: NSLayoutConstraint!
var bubbleRightAnchor: NSLayoutConstraint!
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
backgroundColor = .blue
}
func setupViews() {
addSubview(bubbleView)
addSubview(textView)
bubbleView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
bubbleView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
let viewWidth = UIScreen.main.bounds.width
bubbleWidthAnchor = bubbleView.widthAnchor.constraint(equalToConstant: viewWidth * 0.8)
bubbleWidthAnchor.isActive = true
bubbleLeftAnchor = bubbleView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 8)
bubbleLeftAnchor.isActive = false
bubbleRightAnchor = bubbleView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -8)
bubbleRightAnchor.isActive = true
textView.topAnchor.constraint(equalTo: bubbleView.topAnchor, constant: 4).isActive = true
textView.leftAnchor.constraint(equalTo: bubbleView.leftAnchor, constant: 4).isActive = true
textView.rightAnchor.constraint(equalTo: bubbleView.rightAnchor, constant: -4).isActive = true
textView.bottomAnchor.constraint(equalTo: bubbleView.bottomAnchor, constant: -4).isActive = true
}
//At UICollectionViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ChatBubbleCollectionViewCell
let item = messages[indexPath.item]
if item.fromUserUID == fromUserUID {
cell.bubbleView.backgroundColor = .customPink
cell.textView.text = item.message
cell.textView.textColor = .white
cell.bubbleLeftAnchor.isActive = false
cell.bubbleRightAnchor.isActive = true
} else {
cell.bubbleView.backgroundColor = .faintGray
cell.textView.text = item.message
cell.textView.textColor = .black
cell.bubbleLeftAnchor.isActive = true
cell.bubbleRightAnchor.isActive = false
}
cell.bubbleWidthAnchor.constant = estimatedFrame(for: item.message!).width
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var height: CGFloat = 0
if let text = messages[indexPath.item].message {
height = ceil(estimatedFrame(for: text).height)
}
return CGSize(width: view.frame.width, height: height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func estimatedFrame(for text: String) -> CGRect {
let screenWidthDownsize = UIScreen.main.bounds.width * 0.8
let size = CGSize(width: screenWidthDownsize, height: CGFloat.greatestFiniteMagnitude)
let boundingBox = NSString(string: text).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 17)], context: nil)
return boundingBox
}
The above code gives the following results:
And if I add 50 to the height to expand the cell, like so height = ceil(estimatedFrame(for: text).height) + 50
the results give:
From the images, I suppose one can observe that the boundingBox isn't really giving the right values? What can I try next?