Search code examples
iosautolayout

Top margin (auto-layout)


I set Right Margin for white rect (view) - 1.008

enter image description here

Now I want to set Top Margin - 1.1, but nothing changes (doesn't matter what I set for Multiplier), white rect is still at the top of black rect without any margin:

enter image description here

p.s. I don't want to use constants (I want to set margins in percentages depends on parent view, seems multiplier is designed for this)

Update (example of what I want)

enter image description here


Solution

  • Autolayout here works as expected. Your problem is a simple math problem. Your superview top is located at 0, and for your constraint this holds (read more about constraints anatomy here):

    yourView.top = multiplier * superView.top + constant
    

    After filling in the values:

    yourView.top = 0 * 1.1 + 0
    

    Which is simply:

    yourView.top = 0
    

    In your question the right spacing works, because the superView.right definitely larger than 0 (from what I see on the picture, it's closing to UIScreen.main.bounds.width).

    Update

    To get what you want, I would normally recommend using UILayoutGuide, but since you are using storyboards (where it is not supported), you will have to add a dummy transparent UIView.

    The layout to get what you want would need to look like this (I used .red color instead of .clear so that you can see what I am trying to achieve):

    enter image description here

    In this scenario, you will need to set up following constraints. I will use programmatic way of setting them, but I believe you can easily read them and transform them to storyboards:

    First, constrain the transparent (in my view red) dummy view to the top right corner of the black view - blackView):

    // by default constant = 0, multiplier = 1
    dummyView.topAnchor.constraint(equalTo: blackView.topAnchor).isActive = true
    // right or trailing, it's up to you
    dummyView.rightAnchor.constraint(equalTo: blackView.rightAnchor).isActive = true
    

    Then constrain the dummyView to be a perfect square (width equal to height):

    // by default constant = 0, multiplier = 1
    dummyView.widthAnchor.constraint(equalTo: dummyView.heightAnchor).isActive = true
    

    Keep the right side constraint of the whiteView as it was, and use it to determine the size of the dummyView:

    dummyView.leftAnchor.constraint(equalTo: whiteView.leftAnchor).isActive = true
    

    After this, dummyView will have size of the offset x offset, because its left side is constrained to whiteView.right, and its right side to blackView.right.

    So now you finish with one last constraint which will position whiteView properly from the top:

    whiteView.topAnchor.constraint(equalTo: dummyView.bottomAnchor).isActive = true