Reputation: 3
I'm creating a bubble chat like application. I created custom functions for the receiving and sending bubble chats.
After creating them, I've added them into the cells that I've created using the UITableView.
However, I am not able to set the height of the cell, depending on the height of the custom cell itself.
For example, some text passed in could be longer than the one before.
Thus I can't seem to set each cell according to the custom bubble chat height.
Please help!
This are my tableview functions
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrMsg.count
}
// second
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
// lastly created
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)
if arrMsg[indexPath.row]["type"] as! String == "outgoing" {
cell.contentView.addSubview(createOutGoingBubble(msg: arrMsg[indexPath.row]["message"] as! String))
}
if arrMsg[indexPath.row]["type"] as! String == "incoming" {
cell.contentView.addSubview(createIncomingBubble(mymsg: arrMsg[indexPath.row]["message"] as! String))
}
return cell
}
This is how it looks currently
How do I set the height of the cell according to the custom bubble created inside the heightforrowat function?
Probably using the line to find the height and return it:
arrMsg[indexPath.row]["message"] as! String == "outgoing"
**This is my function to create the custom bubble chats to be added into the tableviewcell
func createOutGoingBubble(msg:String) -> UIView {
let subV = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
let label = UILabel()
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 18)
label.textColor = .white
label.text = msg
let constraintRect = CGSize(width: 0.66 * view.frame.width,
height: .greatestFiniteMagnitude)
let boundingBox = msg.boundingRect(with: constraintRect,
options: .usesLineFragmentOrigin,
attributes: [.font: label.font],
context: nil)
label.frame.size = CGSize(width: ceil(boundingBox.width),
height: ceil(boundingBox.height))
let bubbleSize = CGSize(width: label.frame.width + 28,
height: label.frame.height + 20)
let outgoingMessageView = UIImageView(frame:
CGRect(x: view.frame.width - bubbleSize.width - 20,
y: bubbleSize.height - 25,
width: bubbleSize.width,
height: bubbleSize.height))
let bubbleImage = UIImage(named: "outgoing")?
.resizableImage(withCapInsets: UIEdgeInsets(top: 17, left: 21, bottom: 17, right: 21),
resizingMode: .stretch)
.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
outgoingMessageView.image = bubbleImage
outgoingMessageView.tintColor = UIColor(red: 0.40 , green: 0.71, blue: 1.00, alpha: 1)
subV.addSubview(outgoingMessageView)
label.center = outgoingMessageView.center
subV.addSubview(label)
return subV
}
Thanks in advance!
Upvotes: 0
Views: 1789
Reputation: 43
You can try this:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let cell = tableView.cellForRow(at: indexPath) else { return 0 }
return cell.intrinsicContentSize.height
}
The intrinsicContentSize is the natural size for the receiving view, considering only properties of the view itself.
Upvotes: 0
Reputation: 285
You can use Autolayout for the same and get free from all the coding part. Just set the constraint of the inner view in association with the cell and then right the following code.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:ChatSenderTableViewCell = (tableView.dequeueReusableCell(withIdentifier: "ChatSenderTableViewCell", for: indexPath) as? ChatSenderTableViewCell)!
cell.LabelChatMessage.text = "Your Message"
cell.LabelChatMessage.numberOfLines = 0
cell.LabelChatMessage.sizeToFit()
return cell
}
I am using a custom cell name ChatSenderTableViewCell to create a bubble like effect containing a label for messages send or receive.
Upvotes: 2
Reputation: 757
Use label inside of view and use margin from top and bottom according to your desire. Also, you need to make 0 number of lines in UIlabel. you can do it by using label.numberoflines = 0. Also, you need to add the following code to change the height of the row according to the text inside it.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Upvotes: -1