Search code examples
iosxcodeautolayoutconstraintsscreen-rotation

How to change position of image for portrait or horizontal alignment in XCode 11


I am trying to take an image from filling the right hand side of the screen when viewed in horizontal orientation, to the top quarter when viewed in portrait.

I've followed lots of guides and points on here, but they all related to older version of XCode that seemingly have things XCode 11 don't - such as selecting constant - or just don't work.

I am completely perplexed as to how this should work as when I add "Vary for traits" it applies the move to all devices. I am sure I must be over thinking this, it must be simpler no?

I am using XCode 11.4 with iOS 13.x> above support.

enter image description here


Solution

  • Start by adding a new view controller - use iPhone 8 layout in Portrait Orientation (wC hR):

    enter image description here

    Add a new UIImageView and position it at the top with about 1/4 the height (doesn't matter how close):

    enter image description here

    Add top / leading / trailing constraints:

    enter image description here

    Add a proportional height constraint, at 0.25:

    enter image description here

    Now change View as to Landscape Orientation (wC hC):

    enter image description here

    It will look like this (as expected):

    enter image description here

    Click Vary for Traits, and select Height because we changed from (wC hR) to (wC hC):

    enter image description here

    Look at the constraints in the Size Inspector, and select This Size Class:

    enter image description here

    Delete the Leading and Proportional Height constraints:

    enter image description here

    and add a Bottom constraint and a Proportional Width (0.5) constraint:

    enter image description here

    And click Done Varying. Now it looks like this:

    enter image description here

    Notice that we have 2 "grayed-out" (inactive) constraints... If you switch back to View as Portrait Orientation, those two constraint will become "active" and the two (wC hC) constraints will show as "inactive".

    Because apps can run in partial screens (iPad multi-tasking), it's advised to no longer think in terms of Portrait and Landscape. Rather, think in terms of size classes / traits.

    If your design warrants, you might also add (wR hR) trait variations.

    Now, if you really want Portrait vs Landscape, you'll need to use some code. Define a set of constraints for Tall/Narrow layout, and another set of constraints for Wide/Short layout. Then implement viewWillTransition(to size: ... and activate / deactivate the appropriate constraints based on the "to size" width > height or height > width.