Ashh
Ashh

Reputation: 569

Set button width to fit dynamic button title

I have my UI structured say Level 1(UP), Level 2(DOWN) with some controls In level 1, I have a label L1 In level 2, I have a button and label L2

In level 2 my button may be removed in runtime and I wanted my label L2 to be aligned to leading edge as L1

I'm facing two problems here

  1. When I set my button title programmatically, I want to set my button such that its width grows when text increases and reduces its width when there is less text content. This isn't happening. Please see below screens the constraints I've in place

  2. When I removed my button from superview, I wanted my L2 label Leading to be aligned to L1 leading. So I created a constraint from L2.leading = L1.leading and prioirty is 999

In this case, the button gets reduces its size to almost 0 even if i have text in that. Please advice me setting this up

enter image description here

enter image description here

Upvotes: 0

Views: 912

Answers (1)

Ratul Sharker
Ratul Sharker

Reputation: 8011

Problem #1:

use .horizontal UIStackview for the button and text. set its distribution to .fill. For the button set contentCompression resistance priority to .required for .horizontal & set contenHugging priority to .required for .horizontal. So the Button will always wrap the text no matter what.

Problem #2:

While placing inside a stackview, you don't have to remove the button from superview. Just hide it using isHidden.

Code Demonstration

class SampleVC: UIViewController {

private var didAddConstraint = false

// Basic Views
private let label: UILabel = {
    let view = UILabel()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.text = "Label"
    return view
}()
private let topButton: UIButton = {
    let view = UIButton()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.setTitle("Button", for: .normal)
    view.setTitleColor(.gray, for: .highlighted)
    view.backgroundColor = .green

    view.setContentHuggingPriority(.required, for: .horizontal)
    view.setContentCompressionResistancePriority(.required, for: .horizontal)

    return view
}()
private let rightLabel: UILabel = {
    let view = UILabel()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.numberOfLines = 0
    view.text = "label"
    view.backgroundColor = .red
    return view
}()
private lazy var stackview: UIStackView = {
    let view = UIStackView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.axis = .horizontal
    view.distribution = .fill

    view.addArrangedSubview(topButton)
    view.addArrangedSubview(rightLabel)
    return view
}()


override func loadView() {
    super.loadView()

    view.addSubview(label)
    view.addSubview(stackview)

    view.setNeedsUpdateConstraints()

    view.backgroundColor = .white
}
override func updateViewConstraints() {
    super.updateViewConstraints()

    if didAddConstraint == false {
        didAddConstraint = true

        // top label
        label.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 16.0).isActive = true
        label.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
        label.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true

        // stackview
        stackview.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 16.0).isActive = true
        stackview.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 8.0).isActive = true
        stackview.rightAnchor.constraint(equalToSystemSpacingAfter: view.rightAnchor, multiplier: 16.0).isActive = true
    }
}



override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

        // TEST Code
        // topButton.setTitle("TEST TEST TEST", for: .normal)
        // topButton.isHidden = true

    }
}

Upvotes: 1

Related Questions