Search code examples
iosswiftxcodenslayoutconstraint

NSLayoutConstraints not setting (swift 3)


I'm using text data from core data to size a message container frame however it appears that the frame isn't being set fast enough if that makes sense. I tried putting the code in override layoutSubviews and setupViews to no avail.

Below is the code for setting the messageContainer frame

    if let messageText = cell?.text {
        let size = CGSize(width: 100, height: 40)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let estimatedFrame = NSString(string: messageText).boundingRect(with: size, options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 12)], context: nil)



        messageContainer.translatesAutoresizingMaskIntoConstraints = false
        messageContainer.frame.size.width = estimatedFrame.width
        messageContainer.frame.size.height = estimatedFrame.height



        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .left , relatedBy: .equal, toItem: messageContainer, attribute: .left, multiplier: 1, constant: 5))

        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .width , relatedBy: .lessThanOrEqual, toItem: messageContainer, attribute: .width, multiplier: 1, constant: 0))

        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .height , relatedBy: .lessThanOrEqual, toItem: messageContainer, attribute: .height, multiplier: 1, constant: 0))



    }

Right now the text just runs off the screen and does not wrap.

Any suggestions?

Edit: I have included a screenshot of what the container should look like behind the messageLabel. The difference between this build and the current one is that the current one is using auto layout which I believe is what's causing the issue... enter image description here


Solution

  • Problem:

    Based on the constraint you have set the auto layout system imposes:

    messageLabel.width <= messageContainer.width

    But this might not what you intend.

    Solution:

    What your real intention is to impose restriction on the right.

    • Remove the width constraint.
    • Don't set the frame of messageContainer, use constraints.
    • Set all this in the cell's initialiser.

    messageLabel.right <= messageContainer.right

    Code:

    addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .right , relatedBy: . lessThanOrEqual, toItem: messageContainer, attribute: .right, multiplier: 1, constant: -5))
    

    Note:

    Please test it and see if it matches your requirements.

    Preferred Solution:

    It would be good if you could use the following: