Reputation: 485
So I have completely coded the whole settings vc for my app using code (no storyboards) and I was wondering how do you make the constraints that you created inequality ones? Meaning that if the app is run on a iPhone 7 plus then the constraints would be as I coded them to be, however when you run the app on a iPhone se everything is on top of each other and not the right proportion. I only know how to do this in storyboards with using inequalities but how do you implement that in code? This is the first time that I am not using storyboards at all, so I am a little new.
Thank you in advance!
some code of what the constraints looks like:
func setupProfileImageView() {
//need x, y, width, height constraints
profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
profileImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 120).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 160).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 160).isActive = true
}
Upvotes: 2
Views: 4514
Reputation: 1090
Your simplest bet would be to stay with your methods, and apply a constant based on an algorithm. For example:
func setupProfileImageView() {
//need x, y, width, height constraints
var idealTop : CGFloat = view.frame.height * (some value) //so that it equals a value that changes with each screen size in a way that you feel ok with
idealTop = idealTop < 60 ? 60 : idealTop //makes sure that the constraint doesnt fall bellow 60..
profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
profileImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: idealTop).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 160).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 160).isActive = true
}
Second, I would recommend that for any layout that implies elements being vertically aligned and in the same level of view hierachy, to distance them by a similar way, and by making sure that each element's topAnchor
refers to the element above it's bottomAnchor
. A little trick you could do, is to store the value of your profileImage's topAnchor into a variable, so that you can access it's value for the other elements, like so:
var profileImageTopAnchor : NSLayoutConstraint?
func setupProfileImageView() {
//need x, y, width, height constraints
var idealTop : CGFloat = view.frame.height * (some value) //so that it equals a value that changes with each screen size in a way that you feel ok with
idealTop = idealTop < 60 ? 60 : idealTop //makes sure that the constraint doesnt fall bellow 60..
profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
profileImageTopAnchor = profileImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: idealTop)
profileImageTopAnchor.isActive = true //otherwise it wont get activated
profileImageView.widthAnchor.constraint(equalToConstant: 160).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 160).isActive = true
}
func setupProfileImageView() {
let topAnchor = profileImageTopAnchor != nil ? profileImageTopAnchor!.constant : (/*Some arbitrary value here .. or repeat as above with a fraction value of the view.frame*/)
let topAnchorValue : CGFloat = topAnchor * (some value) //this way, the spacing will change based on the spacing you declare on top of your image..
//And say that you have three other elements stacked vertically..
elementA.constraint(equalTo: profileImageView.topAnchor, constant: topAnchorValue).isActive = true
elementB.constraint(equalTo: elementA.topAnchor, constant: topAnchorValue).isActive = true
elementC.constraint(equalTo: elementB.topAnchor, constant: topAnchorValue).isActive = true
}
You could go further into detecting the actual screen size, and correlating that with a list to see which phone model is being used.. to then apply specific constraints.. but as this sentence is getting longer, so are the reasons as to why the method above is more straightforward!
Upvotes: 0
Reputation:
Just create two constraints - one for minimum (greaterThanOrEqualTo
) and one for maximum (lessThanOrEqualTo
).
myButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 60).isActive = true
myButton.widthAnchor.constraint(lessThanOrEqualToConstant: 120).isActive = true
There's a few tricks to do if you need set priorities, but it doesn't appear that you need to. If you've placed everything correctly (X and Y) this should do it.
Upvotes: 2