Search code examples
swiftuitableviewuikitcell

Contraints reset on table cell reuse UIKit


I'm making a chat app and trying to figure out table cells reuse mechanics. I'm having trouble with aligning chat bubbles to left and right, depending on incoming/ougoing message. What i have right now is:

class ConversationTableViewCell: UITableViewCell {
    @IBOutlet weak var messageTextLabel: UILabel?
    @IBOutlet weak var messageView: UIView?
    @IBOutlet weak var trailingPaddingConstraint: NSLayoutConstraint?
    @IBOutlet weak var leadingPaddingConstraint: NSLayoutConstraint?
    
    func configure(with data: ConversationViewController.ConversationDataModel.Message) {
        
        messageView?.layer.cornerRadius = 12
        messageTextLabel?.text = data.text
        
        switch data.messageType {
        case .incoming:
            trailingPaddingConstraint?.isActive = false
            leadingPaddingConstraint?.isActive = true
            messageView?.backgroundColor = UIColor(named: "IncomingMessage") ?? .gray
        case .outgoing:
            trailingPaddingConstraint?.isActive = true
            leadingPaddingConstraint?.isActive = false
            messageView?.backgroundColor = UIColor(named: "OutgoingMessage") ?? .green
        }
    }
}

as you can see i'm enabling or disabling the needed constraint depending on message type, but it seems like these constraints (and only them) reset when a cell is being reused, causing the bubble to align to leading side. What can i do to successfully update constraints and not run into such problem?


Solution

  • I figured out that setting .isActive to false actually removes the constraint (sets the property to nil). As stated in this answer i tried to make constraint class properties not weak and everything worked!

    now code looks like this:

    class ConversationTableViewCell: UITableViewCell {
        @IBOutlet weak var messageTextLabel: UILabel?
        @IBOutlet weak var messageView: UIView?
        @IBOutlet var trailingPaddingConstraint: NSLayoutConstraint? //not weak
        @IBOutlet var leadingPaddingConstraint: NSLayoutConstraint? //not weak
        
        func configure(with data: ConversationViewController.ConversationDataModel.Message) {
            messageView?.layer.cornerRadius = 12
            messageTextLabel?.text = data.text
            
            switch data.messageType {
            case .incoming:
                trailingPaddingConstraint?.isActive = false
                leadingPaddingConstraint?.isActive = true
                messageView?.backgroundColor = UIColor(named: "IncomingMessage") ?? .gray
            case .outgoing:
                trailingPaddingConstraint?.isActive = true
                leadingPaddingConstraint?.isActive = false
                messageView?.backgroundColor = UIColor(named: "OutgoingMessage") ?? .green
            }
        }
        
    }