38

Let's assume I have this layout design on an iPad Portrait.

Screen1

But I would like to have it this way when the iPad is in landscape: screen2

Is it possible to do that with auto layout? Or with a small amount of code?

Brian
  • 14,610
  • 7
  • 35
  • 43
user2529173
  • 1,884
  • 6
  • 30
  • 43
  • Yes, it is possible. The trick is to hold a reference to all constraints. Then when the orientation changes replace all constraints with the new constraints and again hold a reference. – dasdom Dec 15 '15 at 15:31
  • isnt it easier to have two storyboards for portraint and landscape?@dasdom – Teja Nandamuri Dec 15 '15 at 15:34
  • 1
    @Mr.T no. This should be done in 1 storyboard – Sam B Dec 15 '15 at 15:48
  • See this answer for forcing iPad landscape to use height=compact traits: https://stackoverflow.com/questions/26633172/sizing-class-for-ipad-portrait-and-landscape-modes/28268200#28268200 – InfalibleCoinage Jul 08 '18 at 00:58

9 Answers9

29

You can achieve this through code First of all you have to make IBoutlet of your dynamic constraints

Constant Constraint: // these constraint will remain same in both orientations

1- RedView top Space to Superview

2- RedView Trailing Space to Superview

3- BlueView Leading Space to Superview

4- BlueView bottom Space to SuperView

Dynamic Constraint

Portrait Constraint:

1- RedView height

2- RedView Vertical Space to BlueView

3- RedView Leading Space to Superview

4- BlueView Trailing Space to Superview

LandScape Constraint:

1- RedView Width

2- RedView Horizontal Space to BlueView

3- RedView bottom Space to Superview

4- BlueView Top Space to Superview

Now You have to override method which is called on Orientation change

override func viewWillTransitionToSize(size: CGSize,   withTransitionCoordinator coordinator:    UIViewControllerTransitionCoordinator) {

    coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in

        let orient = UIApplication.sharedApplication().statusBarOrientation

        switch orient {
        case .Portrait:
            print("Portrait")
            self.ApplyportraitConstraint()
            break
            // Do something
        default:
            print("LandScape")
            // Do something else
            self.applyLandScapeConstraint()
            break
        }
        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            print("rotation completed")
    })
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

And call these 2 functions

Portrait Orientation Function

func ApplyportraitConstraint(){

 self.view.addConstraint(self.RedViewHeight)
 self.view.addConstraint(self.RedView_VerticalSpace_To_BlueView)
 self.view.addConstraint(self.RedView_LeadingSpace_To_SuperView)
 self.view.addConstraint(self.BlueView_TrailingSpace_To_SuperView)

 self.view.removeConstraint(self.RedViewWidth)
 self.view.removeConstraint(self.RedView_HorizontalSpace_To_BlueView)
 self.view.removeConstraint(self.RedView_BottomSpace_To_SuperView)          
 self.view.removeConstraint(self.BlueView_TopSpace_To_SuperView)


}

LandScape Orientation Function

    func applyLandScapeConstraint(){

    self.view.removeConstraint(self.RedViewHeight)
    self.view.removeConstraint(self.RedView_VerticalSpace_To_BlueView)
    self.view.removeConstraint(self.RedView_LeadingSpace_To_SuperView)
   self.view.removeConstraint(self.BlueView_TrailingSpace_To_SuperView)

    self.view.addConstraint(self.RedViewWidth)
    self.view.addConstraint(self.RedView_HorizontalSpace_To_BlueView)
    self.view.addConstraint(self.RedView_BottomSpace_To_SuperView)
    self.view.addConstraint(self.BlueView_TopSpace_To_SuperView)

}

Portrait ScreenShot: enter image description here LandScape ScreenShot: enter image description here

Hope it will Help to Understand it through Layout Managment through coding. If you still not able to Understand then Please Check my Code on

Github:

If you have warnings just set height and width's constraint priority to 999.

Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
Muhammad Waqas Bhati
  • 2,775
  • 20
  • 25
14

iPAD don't have the size class for Landscape mode. I think the reason is that it is not needed in most of the cases. However one can activate and deactivate constraints when device orientation change like the accepted answer.

The following can be helpful for iPhone user.

Yes this is possible in interface builder with autolayout and size classes. You will not need to code.

First you select size class wAny hAny

Here is how to select size class.

enter image description here

Add two views in your view controller. Red view on top and blue view below. Just like your first image.

Constraints on red view are:

  • Top space to super view
  • Leading space to super view
  • Trailing space to super view
  • height = 50

Constraints on blue view are:

  • vertical space to red view
  • leading space to super view
  • trailing space to super view
  • bottom space to super view

This is all set for Potrait mode.

Now you change size classes to wAny hCompact(The first two column in first row). this class is for iPhone landscape.

Now you have to use install and uninstall concept.

Constraints that will change for red view:

  • Uninstall its height constriant for (wAny hCompact) size class as:

enter image description here

  • Similary uninstall its Leading constraint. Add two new constraints to this red view in this class:
  • Bottom space to superview
  • Width constraint = 50

This will make red view to right side with 50 width.

Now constraint change for blue view:

  • Uninstall Its vertical spacing, trailing space.

Add two new constraint:

  • Vertical space to super view
  • Trailing space to red View

This will attach red view left of blue view.

Hope it work for you.

Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
Irfan
  • 5,070
  • 1
  • 28
  • 32
5

I Implemented this with Obj-C and published on my github The solution involves a little amount of code, and most of the work is focused in AutoLayout and naming conventions... The README file explains how I did it. The code I used on the ViewController is basically this method:

- (void)setUpViewConstraintsForInterfaceOrientation:(InterfaceOrientation)interfaceOrientation {
    self.lastOrientation = interfaceOrientation;
    if (interfaceOrientation == Landscape) {
        [NSLayoutConstraint deactivateConstraints:self.portraitConstraintsCollection];
        [NSLayoutConstraint activateConstraints:self.landscapeConstraintsCollection];
    } else if(interfaceOrientation == Portrait){
        [NSLayoutConstraint deactivateConstraints:self.landscapeConstraintsCollection];
        [NSLayoutConstraint activateConstraints:self.portraitConstraintsCollection];
    }
    [self.view layoutIfNeeded];
}

portraitConstraintsCollection and landscapeConstraintsCollection are IBOutletCollection properties to manage the orientation's specific constraints.

And the autolayout solution only works with installing and uninstalling constraints (activate and deactivate), no need to add or remove constraints.

mbm29414
  • 11,558
  • 6
  • 56
  • 87
JRafaelM
  • 861
  • 2
  • 10
  • 23
  • 1
    This sounds like a clean approach. I wish Apple allowed us to explicitly create different layouts for orientation in Storyboard itself! – Deepak Sharma Sep 12 '17 at 11:51
4

Is it possible to do that with auto layout? Or with a small amount of code?

You will need both to do these layout for an iPad.

  1. Define your layout constraints for each view, do not set the width or hight constraints for these views.
  2. Wire up IBOutlets for each constraint on view one and two.
  3. Implement the UIContentContainer protocol in your view controller.

    viewWillTransitionToSize(_ size: CGSize,withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)

Discussion UIKit calls this method before changing the size of a presented view controller’s view. You can override this method in your own objects and use it to perform additional tasks related to the size change. For example, a container view controller might use this method to override the traits of its embedded child view controllers. Use the provided coordinator object to animate any changes you make.

If you override this method in your custom view controllers, always call super at some point in your implementation so that UIKit can forward the size change message appropriately. View controllers forward the size change message to their views and child view controllers. Presentation controllers forward the size change to their presented view controller.

Is the method you need to implement. Inside this method you will need to inspect the size's properties width and height to work out how your layout should change - i.e. landscape or portrait layout. Note that this method tell's that it WILL change to the passed in size.

  1. Adjust your constraints based on if the device is going to rotate to portrait or landscape.
Teo
  • 125
  • 1
  • 11
Peter Hornsby
  • 4,208
  • 1
  • 25
  • 44
4

it is much easier to put those two views in a stack view and change the axis orientation for the stackview.

  1. create a IBOulet reference to the stackview
  2. implement viewWillTransitionToSize
  3. change the axis for each orientation by doing self.stackView.axis = .vertical or .horizontal
Rick Pasveer
  • 480
  • 7
  • 12
  • 1
    Indeed, here's a neat tutorial on that specific solution https://www.natashatherobot.com/magical-view-rotation-with-stackview/ However it doesn't save the basic idiocy that Apple make the size classes the same both ways on iPad – Fattie Jul 24 '19 at 11:44
4

My task was the similar in general. I was needing portrait and landscape constraints for both iPhone and iPad. Moreover, yellow and grey views location should be the same in general, but the width of yellow view should be different in iPhone landscape and in iPad landscape (40% of the screen in iPhone and 60% of the screen in iPad): enter image description here

Constraints for iPhone orientations I've set using traits collections and defining for each constraint for what collection it should be installed. For iPhone there are wChR (portrait) and wChC (landscape). Or wC with hAny:

enter image description here

But for landscape and portrait orientations on iPad the single traits collections are used (wRhR) therefore the way used for iPhone is not suitable. To change constraints for these cases I wares up two constraints sets (the first for iPad in landscape and the second for iPad in portrait):

@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *ipadLandscapeConstraints;
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *ipadPortraitConstraints;

Note: 1. To do it select several required constraints in storyboard and wire up them to your .m file. To see what constraints were added to array, click ‘+’ button in he left for the property in .m file: enter image description here 2. I used constraints priority to solve constraints conflicts for iPad

Finally, I’ve implemented configConstraints method to switch constraints sets according to iPad orientation and have overridden viewWillTransitionToSize method:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [self configConstraints];
}

- (void)configConstraints {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // iPad landscape orientation
        if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
            [NSLayoutConstraint deactivateConstraints:self.ipadPortraitConstraints];
            [NSLayoutConstraint activateConstraints:self.ipadLandscapeConstraints];
        }
        // iPad portrait orientation
        else {
            [NSLayoutConstraint deactivateConstraints:self.ipadLandscapeConstraints];
            [NSLayoutConstraint activateConstraints:self.ipadPortraitConstraints];
        }
        [self.view layoutIfNeeded];
    }
}

May be it would be required to call configConstraints method in other places where the view is loading or appearing, but the base idea is described above.

Yulia
  • 1,087
  • 9
  • 16
3

Note - the answers here are good and do address the problem, but on older versions of iOS.

For iOS11 (Xcode 9) you should consider Adaptive Layouts as referenced here: https://www.raywenderlich.com/162311/adaptive-layout-tutorial-ios-11-getting-started

Matt
  • 693
  • 9
  • 16
  • 17
    Perhaps someone could explain how this answers the question. Reading through the tutorial and downloading the example, the two top level views change positions like in the question for iPhone layouts but not iPad. This is exactly the problem, the size classes/traits are the same for iPad portrait and iPad landscape. Maybe I'm missing something... – InfalibleCoinage Jul 08 '18 at 00:51
  • It's a challenging topic, in-short when you upgrade your project to use universal storyboards / adaptive layouts you will have a *single* storyboard that works for all devices (so one "Main Interface" listed in your project/target/general tab in XCode vs two). I've been working my way through the videos and tutorials here for additional assistance: https://developer.apple.com/design/adaptivity/ – Matt Jul 09 '18 at 11:22
  • 10
    Yes, indeed, a single storyboard/xib is the proper way. However, Apple does not differentiate size classes/traits for iPad portrait vs landscape. Your answer indicating that this has changed in iOS 11 seems not to be the case and various workarounds are still need to be used to get this behavior. – InfalibleCoinage Jul 09 '18 at 17:36
0

The only way I have easily achieved this, so it works on iPads and iPhones is by doing it programmatically. This is done with Swift 5.0 in Xcode 10.2.

In your ViewController, define the two views you want to change depending on orientation:

@IBOutlet weak var raceInfoView: UIStackView!
@IBOutlet weak var raceListView: UITableView!

Then define the constraints which will always stay the same in your storyboard and define the ones which will change in your ViewController.

private var portraitRaceInfoViewTrailing: NSLayoutConstraint!
private var portraitRaceInfoViewBottom: NSLayoutConstraint!
private var portraitRaceListViewLeading: NSLayoutConstraint!
private var landscapeRaceInfoViewTrailing: NSLayoutConstraint!
private var landscapeRaceInfoViewBottom: NSLayoutConstraint!
private var landscapeRaceListViewTop: NSLayoutConstraint!

Next, initialise the constraints, I put it in viewDidLoad but it can probably be put somewhere else.

override func viewDidLoad() {
    super.viewDidLoad()

    portraitRaceInfoViewTrailing = NSLayoutConstraint(
        item: racesView as Any, attribute: NSLayoutConstraint.Attribute.trailing,
        relatedBy: NSLayoutConstraint.Relation.equal,
        toItem: raceInfoView, attribute: NSLayoutConstraint.Attribute.trailing,
        multiplier: 1, constant: 0)
    portraitRaceInfoViewBottom = NSLayoutConstraint(
        item: raceListView as Any, attribute: NSLayoutConstraint.Attribute.top,
        relatedBy: NSLayoutConstraint.Relation.equal,
        toItem: raceInfoView, attribute: NSLayoutConstraint.Attribute.bottom,
        multiplier: 1, constant: 0)
    portraitRaceListViewLeading = NSLayoutConstraint(
        item: raceListView as Any, attribute: NSLayoutConstraint.Attribute.leading,
        relatedBy: NSLayoutConstraint.Relation.equal,
        toItem: racesView, attribute: NSLayoutConstraint.Attribute.leading,
        multiplier: 1, constant: 0)

    landscapeRaceInfoViewTrailing = NSLayoutConstraint(
        item: raceListView as Any, attribute: NSLayoutConstraint.Attribute.leading,
        relatedBy: NSLayoutConstraint.Relation.equal,
        toItem: raceInfoView, attribute: NSLayoutConstraint.Attribute.trailing,
        multiplier: 1, constant: 0)
    landscapeRaceInfoViewBottom = NSLayoutConstraint(
        item: raceInfoView as Any, attribute: NSLayoutConstraint.Attribute.bottom,
        relatedBy: NSLayoutConstraint.Relation.equal,
        toItem: racesView, attribute: NSLayoutConstraint.Attribute.bottom,
        multiplier: 1, constant: 0)
    landscapeRaceListViewTop = NSLayoutConstraint(
        item: raceListView as Any, attribute: NSLayoutConstraint.Attribute.top,
        relatedBy: NSLayoutConstraint.Relation.equal,
        toItem: racesView, attribute: NSLayoutConstraint.Attribute.top,
        multiplier: 1, constant: 0)

    applyOrientationConstraints()
}

Declaring constraints programmatically looks a bit scary, but its actually quite easy. You can create the constraint in your storyboard and view all the values and copy the right ones to the right place in the code.

And finally in viewDidLoad apply the constraints with applyOrientationConstraints().

func applyOrientationConstraints() {
    let orient = UIApplication.shared.statusBarOrientation
    switch orient {
    case .portrait:
        NSLayoutConstraint.activate([portraitRaceInfoViewTrailing, portraitRaceInfoViewBottom, portraitRaceListViewLeading])
        NSLayoutConstraint.deactivate([landscapeRaceInfoViewTrailing, landscapeRaceInfoViewBottom, landscapeRaceListViewTop])
        break
    default:
        NSLayoutConstraint.deactivate([portraitRaceInfoViewTrailing, portraitRaceInfoViewBottom, portraitRaceListViewLeading])
        NSLayoutConstraint.activate([landscapeRaceInfoViewTrailing, landscapeRaceInfoViewBottom, landscapeRaceListViewTop])
        break
    }
}

And lastly override viewWillTransition to apply the constraints when the orientation changes.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) -> Void in
        self.applyOrientationConstraints()
    }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
        print("rotation completed")
    })
    super.viewWillTransition(to: size, with: coordinator)
}
just_user
  • 11,769
  • 19
  • 90
  • 135
-1

my two cents.. swift 5:

(pls connect outlet....)

//
//  ViewController.swift
//  AutoLayoutSampleOnRotation
//
//  Created by ing.conti on 13/09/2019.
//  Copyright © 2019 ing.conti. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var redView: UIView!
    @IBOutlet weak var yellowView: UIView!

    private var red_TopPortrait : NSLayoutConstraint?
    private var red_TopLandscape : NSLayoutConstraint?

    private var red_LeftPortrait : NSLayoutConstraint?
    private var red_LeftLandscape : NSLayoutConstraint?

    private var red_RightPortrait : NSLayoutConstraint?
    private var red_RightLandscape : NSLayoutConstraint?

    private var red_BottomPortrait : NSLayoutConstraint?
    private var red_BottomLandscape : NSLayoutConstraint?

    private var red_HeightPortrait : NSLayoutConstraint?
    private var red_WidthLandscape : NSLayoutConstraint?


    ///
    private var yellow_TopPortrait : NSLayoutConstraint?
    private var yellow_TopLandscape : NSLayoutConstraint?

    private var yellow_LeftPortrait : NSLayoutConstraint?
    private var yellow_LeftLandscape : NSLayoutConstraint?

    private var yellow_RightPortrait : NSLayoutConstraint?
    private var yellow_RightLandscape : NSLayoutConstraint?

    private var yellow_BottomPortrait : NSLayoutConstraint?
    private var yellow_BottomLandscape : NSLayoutConstraint?


    private let H_SpaceBetween = CGFloat(20)
    private let V_SpaceBetween = CGFloat(50)

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.


        redView.translatesAutoresizingMaskIntoConstraints = false
        yellowView.translatesAutoresizingMaskIntoConstraints = false

        buildConstraintsForRed()
        buildConstraintsForYellow()

        applyConstraints()
    }



    final private func buildConstraintsForRed(){

        let portraitTopMargin = CGFloat(70)
        let portraitLeftMargin = CGFloat(70)
        let portraitRightMargin = CGFloat(70)

        let landscapeTopMargin = CGFloat(70)
        let landscapeLeftMargin = CGFloat(70)
        let landscapeBottomMargin = CGFloat(70)

        // TOP P
        red_TopPortrait = NSLayoutConstraint(item: redView as Any,
                                             attribute: .top,
                                             relatedBy: .equal,
                                             toItem: self.view,
                                             attribute: .top,
                                             multiplier: 1,
                                             constant: portraitTopMargin)
        red_TopPortrait!.identifier = "red_TopPortrait"

        // LEFT-Heading P
        red_LeftPortrait = NSLayoutConstraint(item: redView as Any,
                                              attribute: .leading,
                                              relatedBy: .equal,
                                              toItem: self.view,
                                              attribute: .leading,
                                              multiplier: 1,
                                              constant: portraitLeftMargin)
        red_LeftPortrait!.identifier = "red_LeftPortrait"

        // RIGHT - trailing P
        red_RightPortrait = NSLayoutConstraint(item: redView as Any,
                                               attribute: .trailing,
                                               relatedBy: .equal,
                                               toItem: self.view,
                                               attribute: .trailing,
                                               multiplier: 1,
                                               constant: -portraitRightMargin)
        red_RightPortrait!.identifier = "red_RightPortrait"

        // BOTTOM: P
        red_BottomPortrait = NSLayoutConstraint(item: redView as Any,
                                                attribute: .bottom,
                                                relatedBy: .equal,
                                                toItem:  yellowView,
                                                attribute: .top,
                                                multiplier: 1,
                                                constant: -V_SpaceBetween)
        red_BottomPortrait!.identifier = "red_BottomPortrait"

        // HEIGHT: P
        red_HeightPortrait = NSLayoutConstraint(item: redView as Any,
                                          attribute: .height,
                                          relatedBy: .equal,
                                          toItem: self.view,
                                          attribute: .height,
                                          multiplier: 0.3,
                                          constant: 0)
        red_HeightPortrait?.identifier = "red_HeightPortrait"



        //LANDSCAPE
        // TOP L
        red_TopLandscape = NSLayoutConstraint(item: redView as Any,
                                              attribute: .top,
                                              relatedBy: .equal,
                                              toItem: self.view,
                                              attribute: .top,
                                              multiplier: 1,
                                              constant: landscapeTopMargin)
        red_TopLandscape!.identifier = "red_TopLandscape"

        // LEFT-Heading L
        red_LeftLandscape = NSLayoutConstraint(item: redView as Any,
                                               attribute: .leading,
                                               relatedBy: .equal,
                                               toItem: self.view,
                                               attribute: .leading,
                                               multiplier: 1,
                                               constant: landscapeLeftMargin)
        red_LeftLandscape!.identifier = "red_LeftLandscape"


        // RIGHT - trailing L
        red_RightLandscape = NSLayoutConstraint(item: redView as Any,
                                                attribute: .trailing,
                                                relatedBy: .equal,
                                                toItem: yellowView,
                                                attribute: .leading,
                                                multiplier: 1,
                                                constant: -H_SpaceBetween)
        red_RightLandscape!.identifier = "red_RightLandscape"


        // BOTTOM: L
        red_BottomLandscape = NSLayoutConstraint(item: redView as Any,
                                                 attribute: .bottom,
                                                 relatedBy: .equal,
                                                 toItem: self.view,
                                                 attribute: .bottom,
                                                 multiplier: 1,
                                                 constant: -landscapeBottomMargin)
        red_BottomLandscape?.identifier = "red_BottomLandscape"

        // Width L:
        red_WidthLandscape = NSLayoutConstraint(item: redView as Any,
                                          attribute: .width,
                                          relatedBy: .equal,
                                          toItem: self.view,
                                          attribute: .width,
                                          multiplier: 0.3,
                                          constant: 0)
        red_WidthLandscape!.identifier = "red_WidthLandscape"
    }


    final private func buildConstraintsForYellow(){

        let portraitLeftMargin = CGFloat(20)
        let portraitRightMargin = CGFloat(20)
        //let portraitHorizMargin = CGFloat(100)
        let portraitBottomMargin = CGFloat(20)

        let landscaspeTopMargin = CGFloat(20)
        let landscaspeRightMargin = CGFloat(20)
        let landscapeBottomMargin = CGFloat(20)


        // TOP P
        yellow_TopPortrait = NSLayoutConstraint(item: yellowView as Any,
                                             attribute: .top,
                                             relatedBy: .equal,
                                             toItem: redView,
                                             attribute: .bottom,
                                             multiplier: 1,
                                             constant: V_SpaceBetween)
        yellow_TopPortrait!.identifier = "yellow_TopPortrait"

        // LEFT-Heading P
        yellow_LeftPortrait = NSLayoutConstraint(item: yellowView as Any,
                                                 attribute: .leading,
                                                 relatedBy: .equal,
                                                 toItem: self.view,
                                                 attribute: .leading,
                                                 multiplier: 1,
                                                 constant: portraitLeftMargin)
        yellow_LeftPortrait!.identifier = "yellow_LeftPortrait"

        // RIGHT - trailing P
        yellow_RightPortrait = NSLayoutConstraint(item: yellowView as Any,
                                                  attribute: .trailing,
                                                  relatedBy: .equal,
                                                  toItem: self.view,
                                                  attribute: .trailing,
                                                  multiplier: 1,
                                                  constant: -portraitRightMargin)
        yellow_RightPortrait!.identifier = "yellow_RightPortrait"

        // BOTTOM: P
        yellow_BottomPortrait = NSLayoutConstraint(item: yellowView as Any,
                                                   attribute: .bottom,
                                                   relatedBy: .equal,
                                                   toItem: self.view,
                                                   attribute: .bottom,
                                                   multiplier: 1,
                                                   constant: -portraitBottomMargin)
        yellow_BottomPortrait!.identifier = "yellow_BottomPortrait"

        //LANDSSCAPE
        // TOP L
        yellow_TopLandscape = NSLayoutConstraint(item: yellowView as Any,
                                              attribute: .top,
                                              relatedBy: .equal,
                                              toItem: self.view,
                                              attribute: .top,
                                              multiplier: 1,
                                              constant: landscaspeTopMargin)
        yellow_TopLandscape!.identifier = "yellow_TopLandscape"

        // LEFT-Heading L
        yellow_LeftLandscape = NSLayoutConstraint(item: yellowView as Any,
                                               attribute: .leading,
                                               relatedBy: .equal,
                                               toItem: self.redView,
                                               attribute: .trailing,
                                               multiplier: 1,
                                               constant: H_SpaceBetween)
        yellow_LeftLandscape!.identifier = "yellow_LeftLandscape"

        // RIGHT - trailing L
        yellow_RightLandscape = NSLayoutConstraint(item: yellowView as Any,
                                                attribute: .trailing,
                                                relatedBy: .equal,
                                                toItem: self.view,
                                                attribute: .trailing,
                                                multiplier: 1,
                                                constant: -landscaspeRightMargin)
        yellow_RightLandscape!.identifier = "yellow_RightLandscape"

        // BOTTOM: L
        yellow_BottomLandscape = NSLayoutConstraint(item: yellowView as Any,
                                                 attribute: .bottom,
                                                 relatedBy: .equal,
                                                 toItem: self.view,
                                                 attribute: .bottom,
                                                 multiplier: 1,
                                                 constant: -landscapeBottomMargin)
        yellow_BottomLandscape!.identifier = "yellow_BottomLandscape"
    }


    final private  func removeRedConstraints() {
        if let c = red_LeftPortrait  {self.view.removeConstraint(c)}
        if let c = red_LeftLandscape  {self.view.removeConstraint(c)}

        if let c = red_RightPortrait  {self.view.removeConstraint(c)}
        if let c = red_RightLandscape  {self.view.removeConstraint(c)}

        if let c = red_TopPortrait  {self.view.removeConstraint(c)}
        if let c = red_TopLandscape  {self.view.removeConstraint(c)}

        if let c = red_BottomPortrait  {self.view.removeConstraint(c)}
        if let c = red_BottomLandscape  {self.view.removeConstraint(c)}

        if let c = red_HeightPortrait  {self.view.removeConstraint(c)}
        if let c = red_WidthLandscape  {self.view.removeConstraint(c)}



    }


    final private  func removeYellowConstraints() {
        if let c = yellow_LeftPortrait  {self.view.removeConstraint(c)}
        if let c = yellow_LeftLandscape  {self.view.removeConstraint(c)}

        if let c = yellow_RightPortrait  {self.view.removeConstraint(c)}
        if let c = yellow_RightLandscape  {self.view.removeConstraint(c)}

        if let c = yellow_TopPortrait  {self.view.removeConstraint(c)}
        if let c = yellow_TopLandscape  {self.view.removeConstraint(c)}

        if let c = yellow_BottomPortrait  {self.view.removeConstraint(c)}
        if let c = yellow_BottomLandscape  {self.view.removeConstraint(c)}

    }


    final private func applyPortraitConstraint(){
        removeRedConstraints()
        removeYellowConstraints()
        self.view.addConstraint(self.red_LeftPortrait!)
        self.view.addConstraint(self.red_RightPortrait!)
        self.view.addConstraint(self.red_TopPortrait!)
        self.view.addConstraint(self.red_BottomPortrait!)

        self.view.addConstraint(self.red_HeightPortrait!)


        self.view.addConstraint(self.yellow_LeftPortrait!)
        self.view.addConstraint(self.yellow_RightPortrait!)
        self.view.addConstraint(self.yellow_TopPortrait!)
        self.view.addConstraint(self.yellow_BottomPortrait!)
    }

    final private func applyLandscapeConstraint(){
        removeRedConstraints()
        removeYellowConstraints()
        self.view.addConstraint(self.red_LeftLandscape!)
        self.view.addConstraint(self.red_RightLandscape!)
        self.view.addConstraint(self.red_TopLandscape!)
        self.view.addConstraint(self.red_BottomLandscape!)

        self.view.addConstraint(self.red_WidthLandscape!)

        self.view.addConstraint(self.yellow_LeftLandscape!)
        self.view.addConstraint(self.yellow_RightLandscape!)
        self.view.addConstraint(self.yellow_TopLandscape!)
        self.view.addConstraint(self.yellow_BottomLandscape!)
    }




    final private func applyConstraints(){

        let orient = UIApplication.shared.statusBarOrientation

        switch orient {
        case .portrait:
            print("Portrait")
            self.applyPortraitConstraint()
            break
            // Do something

        default:
            print("LandScape")
            // Do something else
            self.applyLandscapeConstraint()
            break
        }

    }






    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {


        coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) -> Void in

            self.applyConstraints()
        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            print("rotation completed")
        })

        super.viewWillTransition(to: size, with: coordinator)
    }
}

IN SIMULATOR.......

Community
  • 1
  • 1
ingconti
  • 10,876
  • 3
  • 61
  • 48