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:
Here is the screenshot in iPhone 15 simulator:
Here is the screenshot on different mode, the right arrow image width is set properly:
As you can see, the width of the rightImageView
property is increased. How can I give fixed width for different device?
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:
and element widths stay the same, regardless of view width:
When you run the above code, tap anywhere to toggle the colors on/off so you can see the framing: