Search code examples
iosswiftnslayoutconstraint

NSLayoutConstraint - Two items, one line, spacing priority


I have two labels on one line. I need the second label to be right up against the end of the first label, but I need to make sure the second label never runs past the edge of the screen.

So I have label1's left anchor aligned to the left of the container view, and I have label2's left anchor constrained to the right of label1, and the right anchor of label2 constrained to the right of the container.

I want label1 to take up only as much space as it needs, and label2 to take up the rest of the space. What I have is exactly the opposite.

enter image description here

So I need the exact opposite of what I have here. How can I do that?


Solution

  • Giving the left label a higher content hugging priority should do the trick.

    // In code
    leftLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
    

    left label content hugging priority

    For further reading on that topic, I found this to be pretty helpful

    Playground example

    //: A UIKit based Playground for presenting user interface
      
    import UIKit
    import PlaygroundSupport
    
    class MyViewController : UIViewController {
        
        override func loadView() {
            let view = UIView()
            view.backgroundColor = .white
    
            let leftLabel = UILabel()
            leftLabel.text = "I am left"
            leftLabel.backgroundColor = .orange
            leftLabel.translatesAutoresizingMaskIntoConstraints = false
            
            let rightLabel = UILabel()
            rightLabel.text = "I am right"
            rightLabel.backgroundColor = .yellow
            rightLabel.translatesAutoresizingMaskIntoConstraints = false
            
            view.addSubview(leftLabel)
            view.addSubview(rightLabel)
            
            leftLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true
            leftLabel.trailingAnchor.constraint(equalTo: rightLabel.leadingAnchor).isActive = true
            leftLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 16).isActive = true
            
            // This is the important part
            leftLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
            
            rightLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16).isActive = true
            rightLabel.topAnchor.constraint(equalTo: leftLabel.topAnchor).isActive = true
            
            self.view = view
        }
    }
    // Present the view controller in the Live View window
    PlaygroundPage.current.liveView = MyViewController()