1

My constraints are broke when I pop VC. I have table view, when I firstly push table view, constraints are work perfectly, but after poping and pushing again they are broke. First image are working good, but in second they are broke Maybe problem is in didSet, after breaking constraints xcode says to remove width, but ui will be bad This is working fine This is are broken This is my cell code

    var isIncoming: Bool! {
        
        didSet {
            bubbleBackgroundView.backgroundColor = isIncoming ? Constants.Color.inComingMessages : Constants.Color.outComingMessages
            messageLabel.textColor = isIncoming ? .black : .white
            
            if isIncoming {
                bubbleBackgroundView.snp.makeConstraints { (make) in
                    make.leading.equalTo(16)
                    make.width.equalTo(180)
                }
                messageLabel.snp.makeConstraints { (make) in
                    make.leading.equalTo(16)
                }
                addSubview(inComingImgTail)
                inComingImgTail.snp.makeConstraints { (make) in
                    make.trailing.equalTo(bubbleBackgroundView.snp.leading).offset(12)
                    make.top.equalTo(bubbleBackgroundView.snp.top).offset(1)
                    make.width.equalTo(15)
                    make.height.equalTo(36)
                }
            }
            else if !isIncoming{
                bubbleBackgroundView.snp.makeConstraints { (make) in
                    make.trailing.equalTo(self).offset(-16)
                    make.width.equalTo(180)
                }
                messageLabel.snp.makeConstraints { (make) in
                    make.leading.equalTo(16)
                    make.trailing.equalTo(-16)
                }
                
                addSubview(OutComingImgTail)
                OutComingImgTail.snp.makeConstraints { (make) in
                    make.trailing.equalTo(bubbleBackgroundView.snp.trailing).offset(4)
                    make.top.equalTo(bubbleBackgroundView.snp.top).offset(1)
                    make.width.equalTo(15)
                    make.height.equalTo(36)
                }
            }
        }
        
    }

This is my dataSource and delegate code


extension ChatVC: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return ChatVC.messagesList.count

    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: MessagesCell.reuseIdentifier, for: indexPath) as! MessagesCell
        

        let messages = ChatVC.messagesList[indexPath.row]
        
        let sorted = ChatVC.messagesList.sorted { (first, second) -> Bool in
            return first.pk < second.pk
        }
        cell.messagesLists = messages
        cell.messageLabel.text = sorted[indexPath.row].text
        
        
        if sorted[indexPath.row].from_user == userID {
            cell.isIncoming = false
            
        }
        else if sorted[indexPath.row].from_user != userID {
            cell.isIncoming = true
            
        }
        
        return cell
    }
    
    
}

2 Answers2

1

The cells are being reused every time, and to switch modes from .sent to .received, you have to deactivate previous constraints. Add two arrays of constraints for both states, and deactivate the previous array and activate the new one. In your case you just append constraints, but don't remove them

var receivedConstraints = [NSLayoutConstraint]()
var sentConstraints = [NSLayoutConstraint]()

...

final func changeCellMode(to mode: SNKMessage.Mode, didChangeMessageMode: (Bool) -> ()) {
    if let _previousMode = previousMessageMode, _previousMode == mode {
        didChangeMessageMode(false)
        messageBackground.setNeedsDisplay()
        return
    }
    
    didChangeMessageMode(true)
    if mode == .outgoing {
        NSLayoutConstraint.deactivate(receivedConstraints)
        NSLayoutConstraint.activate(sentConstraints)
    } else {
        NSLayoutConstraint.deactivate(sentConstraints)
        NSLayoutConstraint.activate(receivedConstraints)
    }
    
    messageBackground.messageMode = mode
    previousMessageMode = mode
    setNeedsLayout()
}
Vitalii Shvetsov
  • 404
  • 2
  • 11
0

First of all, i recommend you to use collectionview for this kind of a view. In this part of source, you should not set constraints every time. By the way please watch the link below. :)

https://youtu.be/kR9cf_K_9Tk

erkutbas
  • 305
  • 2
  • 9