setup all of the properties of the stack view

37 Views Asked by At

I'm using an SF symbol image into a UIImageView. I have given the constrains as well. What I have seen running the same code into different simulators actually increases the width of the image but I want to give fixed width into different iOS simulators.

Here is the code for the image:

let rightImageView: UIImageView = {
    let rightImageView = UIImageView()
    rightImageView.image = UIImage(systemName: "arrow.right")
    rightImageView.translatesAutoresizingMaskIntoConstraints = false
    rightImageView.tintColor = .purple
    return rightImageView
}()

Here is the constrains for it and other properties:

private func setUpUI() {
    view.addSubview(stackview)
    stackview.dm_addArrangedSubviews(titleLable)
    stackview.dm_addArrangedSubviews(viewAllLable)
    stackview.dm_addArrangedSubviews(rightImageView)
    view.addSubview(collectionView)
    
    let safeArea = view.safeAreaLayoutGuide
    NSLayoutConstraint.activate([
        
        stackview.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            stackview.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            stackview.topAnchor.constraint(equalTo: view.topAnchor),
            collectionView.topAnchor.constraint(equalTo: stackview.bottomAnchor),
            collectionView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor),
            collectionView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor),
            collectionView.heightAnchor.constraint(equalToConstant: view.frame.width/2)
    ])
}

Here is the screenshot in iPhone 15 Pro Max: 15th Pro max

Here is the screenshot in iPhone 15 simulator: 15

Here is the screenshot on different mode, the right arrow image width is set properly: different mode

As you can see, the width of the rightImageView property is increased. How can I give fixed width for different device?

1

There are 1 best solutions below

0
DonMag On BEST ANSWER

Set the rightImageView.widthAnchor equal to the rightImageView.heightAnchor.

Set content hugging priority on viewAllLable so it doesn't stretch horizontally.

Quick example:

class ViewController: UIViewController {
    
    let rightImageView: UIImageView = {
        let rightImageView = UIImageView()
        rightImageView.image = UIImage(systemName: "arrow.right")
        rightImageView.tintColor = .purple
        return rightImageView
    }()
    
    let stackview: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.spacing = 8
        return v
    }()
    
    let titleLable: UILabel = {
        let v = UILabel()
        v.font = .systemFont(ofSize: 24.0, weight: .regular)
        v.text = "Similar Movies"
        return v
    }()

    let viewAllLable: UILabel = {
        let v = UILabel()
        v.font = .systemFont(ofSize: 24.0, weight: .regular)
        v.text = "View all"
        return v
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpUI()
    }
    
    private func setUpUI() {
        view.addSubview(stackview)
        stackview.addArrangedSubview(titleLable)
        stackview.addArrangedSubview(viewAllLable)
        stackview.addArrangedSubview(rightImageView)
        
        let safeArea = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            
            // constrain to safeArea, with 8-point "padding" on top/leading/trailing
            stackview.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor, constant: 8.0),
            stackview.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor, constant: -8.0),
            stackview.topAnchor.constraint(equalTo: safeArea.topAnchor, constant: 8.0),
            
            rightImageView.widthAnchor.constraint(equalTo: rightImageView.heightAnchor),
            
        ])
        
        // don't let viewAllLable stretch horizontally
        viewAllLable.setContentHuggingPriority(.required, for: .horizontal)
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // toggle colors so we can see the framing
        if titleLable.backgroundColor == .yellow {
            titleLable.backgroundColor = .clear
            viewAllLable.backgroundColor = .clear
            rightImageView.backgroundColor = .clear
            
            stackview.layer.borderWidth = 0
        } else {
            titleLable.backgroundColor = .yellow
            viewAllLable.backgroundColor = .green
            rightImageView.backgroundColor = .cyan
            
            stackview.layer.borderColor = UIColor.red.cgColor
            stackview.layer.borderWidth = 1
        }
    }
}

Looks like this:

enter image description here

and element widths stay the same, regardless of view width:

enter image description here

When you run the above code, tap anywhere to toggle the colors on/off so you can see the framing:

enter image description here

enter image description here