Jaqueline
Jaqueline

Reputation: 485

Inequality constraints programmatically swift

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

Answers (2)

jlmurph
jlmurph

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

user7014451
user7014451

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

Related Questions