Set up margins in XCode 11

Hi,

I am completely new to iOS development and I'm trying to follow the official tutorial.

It is a bit annoying because it doesn't seem to be up to date, but I managed to get up to this point: https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/BuildABasicUI.html#//apple_ref/doc/uid/TP40015214-CH5-SW1


It is a very simple app with a label, a text field and a button placed vertically in a single stack view.

I am trying to set up the stack view margins so that it takes the safe area into account while also not sticking to the edge of the screen.

What I've done is set constraint so that the top, left and right edge of the stack view stick to the edge of the safe area.


I partially get what I want:

- in portrait, the top of the layout is properly placed but the sides stick to the edge of the screen

- in landscape, the sides of the layout are properly placed but the top of the layout sticks to the top of the screen


I could add a margin of 20 in trailing/leading to make it work while in portrait, but it won't look nice to have those margins when in portrait. Also, it feels like default margins should be defined at the app level and not on every single view ?


I can't believe I'm stuck on such a simple problem, but could anyone tell me what is the recommended way to set up margins when making a new iOS app ?


Thanks

Accepted Reply

Need to more more specific and more accurate as well (I wrote a little too fast).


In fact, the swipe bar is always at bottom. In addition, constraints must be adapted depending you are in Portrait or Landscape.


So, you should:


First set the Interface vertically in IB (that should already be the case, otherwise, tap the View as button at bottom to change orientation) and define constraints for leading, trailing, top and bottom, relative to safe area.

Set the constant value for leading and trailing different than 0 (20 for instance) so that it is not stuck to the borders.


Now, this set of constraints need only to apply in Portrait.


So, select each constraint and edit it in the Size inspector.

Select the first constraint.

At the bottom, you should see a + sign and 'installed' checked.

That means that the constraint applies always.

Now, we want to apply only in Portrait.

- click on the +

- select Width Compact and Height Regular (that's Portrait)

- click Add variation

- uncheck the top checkbox and select instead the one labelled wC hR


Repeat this for all other 3 constraints.


Now, we need to define constraints for Landscape.

At the bottom of XCode click on "View as:" and select landscape orinetation

You have to create new constraints, relative to safe area: control drag from the object (your stack ?) and drag to safe area.

You probably see dots for 4 constraints (the Portrait ones)

Select each (the dot is replaced by a check mark) and hit return


Now, back to the Size editor, you should see that some constraints are greyed out (the Portrait ones).

Double Click on the first constraint in black (should be Horizontal / Align trailing or leading to safe area)

Check its constant : 0 if the notch is on this edge, 20 otherwise)

Now, we want to apply only in Landscape.

- click on the +

- select Width Regular and Height Compact (that's Landscape)

- click Add variation

- uncheck the top checkbox and select instead the one labelled wR hC


Repeat this for all other 3 constraints.

Make sure Top to safe area is 20.


You can run and test rotation now, that's what you wanted.

Replies

I partially get what I want:

- in portrait, the top of the layout is properly placed but the sides stick to the edge of the screen

- in landscape, the sides of the layout are properly placed but the top of the layout sticks to the top of the screen


If I interpret correctly what you did, it rsults as expected.


Safe area is inset only for the notch and the swipe button.

On the other sides it is full screen.


So

- in portrait, the top of the layout is properly placed but the sides stick to the edge of the screen

Normal, because notch is at top and swipe at bottom

and safe area goes to screen limits on left and right


- in landscape, the sides of the layout are properly placed but the top of the layout sticks to the top of the screen

Normal, because now, notch is at left (or right) and swipe at right (or left)

and safe area goes to screen limits on top and bottom


What you should do is change the constraints constants for leading and trailing to 20 vs 0, for instance.

>It is a bit annoying because it doesn't seem to be up to date


Correct - good on you for recognizing, but it's more than just it's shelf life. The FT tutorial can be a mine field for newbies when not approached heads up.


If Claude's trustworthy suggestions don't pan out, I suggest you search here on it as there are several threads that discuss it, and it's issues, and possible means of dealing with, or...find something else, more current, with less baggage.


Also note that Xcode 11 lacks the ability to disable auto layout, if that tactic comes up...


Good luck.

Thanks for your answer.



I understand that the safe area is only here to account for the notches, but it looks like there is another kind of constraint:

- If I look at the tutorial screens, the leading/trailing constraints are set to 0 yet they do not stick to the edge of the screen, there is some kind of default margin.

- If I drag a button manually in the scenario editor, I can also see that it can snap to a guideline, again letting me think that there is some kind of default margin defined somewhere.

Isn't this margin value accessible somewhere in the editor ?


Again, I understand that I can define this margin manually for each view, but I'm looking for a cleaner way to do it throughout the app.

Need to more more specific and more accurate as well (I wrote a little too fast).


In fact, the swipe bar is always at bottom. In addition, constraints must be adapted depending you are in Portrait or Landscape.


So, you should:


First set the Interface vertically in IB (that should already be the case, otherwise, tap the View as button at bottom to change orientation) and define constraints for leading, trailing, top and bottom, relative to safe area.

Set the constant value for leading and trailing different than 0 (20 for instance) so that it is not stuck to the borders.


Now, this set of constraints need only to apply in Portrait.


So, select each constraint and edit it in the Size inspector.

Select the first constraint.

At the bottom, you should see a + sign and 'installed' checked.

That means that the constraint applies always.

Now, we want to apply only in Portrait.

- click on the +

- select Width Compact and Height Regular (that's Portrait)

- click Add variation

- uncheck the top checkbox and select instead the one labelled wC hR


Repeat this for all other 3 constraints.


Now, we need to define constraints for Landscape.

At the bottom of XCode click on "View as:" and select landscape orinetation

You have to create new constraints, relative to safe area: control drag from the object (your stack ?) and drag to safe area.

You probably see dots for 4 constraints (the Portrait ones)

Select each (the dot is replaced by a check mark) and hit return


Now, back to the Size editor, you should see that some constraints are greyed out (the Portrait ones).

Double Click on the first constraint in black (should be Horizontal / Align trailing or leading to safe area)

Check its constant : 0 if the notch is on this edge, 20 otherwise)

Now, we want to apply only in Landscape.

- click on the +

- select Width Regular and Height Compact (that's Landscape)

- click Add variation

- uncheck the top checkbox and select instead the one labelled wR hC


Repeat this for all other 3 constraints.

Make sure Top to safe area is 20.


You can run and test rotation now, that's what you wanted.

Yest, that is a predefined value (20).


If you poistion your view on this grid (e.g, leading margin) and then create a leading constraint, its value (constant) will be set to 20.


But you still need to adapt constraints to orientation.

@Claude31 Thanks a lot for the step by step explanation.

I'm a bit surprised there isn't a way to do this more easily (like declaring the margin values once in a stylesheet or something like that), but it's not a big deal.