ios 纵向和横向模式下的不同布局

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34293073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:24:25  来源:igfitidea点击:

Different layouts in portrait and landscape mode

iosxcodeautolayout

提问by user2529173

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

让我们假设我在 iPad Portrait 上有这个布局设计。

Screen1

屏幕 1

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

但是当 iPad 处于横向时,我想以这种方式使用它: 屏幕2

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

是否可以通过自动布局来做到这一点?还是用少量代码?

采纳答案by Matt

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

注意 - 这里的答案很好并且确实解决了问题,但是在旧版本的 iOS 上。

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

对于 iOS11 (Xcode 9),您应该考虑此处引用的自适应布局https: //www.raywenderlich.com/162311/adaptive-layout-tutorial-ios-11-getting-started

回答by Muhammad Waqas Bhati

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

您可以通过代码实现这一点首先,您必须制作动态约束的IBoutlet

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

Constant Constraint:// 这些约束在两个方向上都保持不变

1- RedView top Space to Superview

1- RedView 顶部空间到 Superview

2- RedView Trailing Space to Superview

2- RedView 尾随空间到 Superview

3- BlueView Leading Space to Superview

3-BlueView引领空间到Superview

4- BlueView bottom Space to SuperView

4- BlueView 底部空间到 SuperView

Dynamic Constraint

动态约束

Portrait Constraint:

肖像约束:

1- RedView height

1- RedView 高度

2- RedView Vertical Space to BlueView

2- RedView 垂直空间到 BlueView

3- RedView Leading Space to Superview

3-RedView引领空间到Superview

4- BlueView Trailing Space to Superview

4- BlueView 尾随空间到 Superview

LandScape Constraint:

景观约束:

1- RedView Width

1- RedView 宽度

2- RedView Horizontal Space to BlueView

2- RedView 水平空间到 BlueView

3- RedView bottom Space to Superview

3- RedView 底部空间到 Superview

4- BlueView Top Space to Superview

4- BlueView 顶部空间到 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 hereLandScape 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:

GitHub

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

如果您有警告,只需将高度和宽度的约束优先级设置为 999。

回答by Irfan

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.

iPad 没有横向模式的尺寸等级。我认为原因是在大多数情况下不需要它。然而,当设备方向像接受的答案一样改变时,可以激活和停用约束。

The following can be helpful for iPhone user.

以下内容可能对 iPhone 用户有所帮助。

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

首先你选择尺寸等级 wAny hAny

Hereis 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
  • 超级视图的顶部空间
  • 领先空间超观
  • 超级视图的尾随空间
  • 高度 = 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.

这都是为 Potrait 模式设置的。

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

现在您将 size classes 更改为 wAny hCompact(第一行的前两列)。这个类是为 iPhone 风景。

Now you have to use installand uninstallconcept.

现在您必须使用安装卸载概念。

Constraints that will change for red view:

将更改为红色视图的约束:

  • Uninstall its height constriant for (wAny hCompact) size class as:
  • 卸载 (wAny hCompact) 尺寸类的高度约束为:

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
  • 类似地卸载其领先的约束。向此类中的此红色视图添加两个新约束:
  • 超级视图的底部空间
  • 宽度约束 = 50

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

这将使右侧具有 50 宽度的红色视图。

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.

希望它对你有用。

回答by Pete Hornsby

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.

您将需要两者来为 iPad 进行这些布局。

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

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

  1. 为每个视图定义布局约束,不要为这些视图设置宽度或高度约束。
  2. 为视图一和视图二上的每个约束连接IBOutlets
  3. 在您的视图控制器中实现UIContentContainer 协议

    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.

讨论 UIKit 在更改呈现的视图控制器视图的大小之前调用此方法。您可以在自己的对象中覆盖此方法,并使用它来执行与大小更改相关的其他任务。例如,容器视图控制器可能使用此方法覆盖其嵌入式子视图控制器的特征。使用提供的协调器对象为您所做的任何更改设置动画。

如果您在自定义视图控制器中覆盖此方法,请始终在您的实现中的某个时刻调用 super,以便 UIKit 可以适当地转发大小更改消息。视图控制器将大小更改消息转发给它们的视图和子视图控制器。展示控制器将尺寸变化转发给它们展示的视图控制器。

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 WILLchange to the passed in size.

是你需要实现的方法。在此方法中,您需要检查尺寸的宽度和高度属性,以确定您的布局应如何更改 - 即横向或纵向布局。注意,此方法泰尔的,它WILL改为在尺寸上通过。

  1. Adjust your constraints based on if the device is going to rotate to portrait or landscape.
  1. 根据设备是要旋转到纵向还是横向来调整您的约束。

回答by Yulia

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

我的任务大致相同。我需要 iPhone 和 iPad 的纵向和横向约束。此外,黄色和灰色视图的位置一般应该是一样的,但是黄色视图的宽度在 iPhone 横向和 iPad 横向应该不同(iPhone 屏幕的 40% 和 iPad 屏幕的 60%): 在此处输入图片说明

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:

iPhone 方向的约束我使用特征集合设置并为每个约束定义应该安装的集合。iPhone 有 wChR(纵向)和 wChC(横向)。或 wC 与 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):

但是对于 iPad 上的横向和纵向方向,使用单个特征集合 (wRhR),因此用于 iPhone 的方式不适合。为了更改这些情况的约束,我准备了两个约束集(第一个用于横向 iPad,第二个用于纵向 iPad):

@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 here2. I used constraints priority to solve constraints conflicts for iPad

注意: 1. 要做到这一点,请在故事板中选择几个必需的约束并将它们连接到您的 .m 文件。要查看添加到数组的约束,请单击左侧的“+”按钮以查看 .m 文件中的属性: 在此处输入图片说明2. 我使用约束优先级来解决 iPad 的约束冲突

Finally, I've implemented configConstraintsmethod to switch constraints sets according to iPad orientation and have overridden viewWillTransitionToSizemethod:

最后,我实现了configConstraints根据 iPad 方向切换约束集的viewWillTransitionToSize方法并重写了方法:

- (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 configConstraintsmethod in other places where the view is loading or appearing, but the base idea is described above.

可能需要configConstraints在视图加载或出现的其他地方调用方法,但基本思想如上所述。

回答by JRafaelM

I Implemented this with Obj-C and published on my githubThe 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:

我用 Obj-C 实现了这个并发布在我的 github解决方案涉及少量代码,大部分工作集中在 AutoLayout 和命名约定...... README 文件解释了我是如何做到的。我在 ViewController 上使用的代码基本上就是这个方法:

- (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.

PortraitConstraintsCollection 和 LandscapeConstraintsCollection 是 IBOutletCollection 属性,用于管理方向的特定约束。

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

并且自动布局解决方案仅适用于安装和卸载约束(激活和停用),无需添加或删除约束。

回答by Rick Pasveer

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
  1. 创建对堆栈视图的 IBoulet 引用
  2. 实现 viewWillTransitionToSize
  3. 通过执行 self.stackView.axis = .vertical 或 .horizo​​ntal 更改每个方向的轴

回答by just_user

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.

我很容易实现这一点的唯一方法是通过编程来实现它,因此它可以在 iPad 和 iPhone 上运行。这是通过 Xcode 10.2 中的 Swift 5.0 完成的。

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

在您的 ViewController 中,定义要根据方向更改的两个视图:

@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.

然后定义在您的故事板中始终保持不变的约束,并定义将在您的 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.

接下来,初始化约束,我把它放在 viewDidLoad 中,但它可能可以放在其他地方。

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().

最后在 viewDidLoad 中应用约束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 viewWillTransitionto apply the constraints when the orientation changes.

最后覆盖viewWillTransition以在方向更改时应用约束。

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)
}

回答by ingconti

my two cents.. swift 5:

我的两分钱.. 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.......

在模拟器中......