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

use*_*173 25 xcode ios autolayout

我们假设我在iPad Portrait上有这种布局设计.

屏蔽1

但是当iPad处于风景中时,我想这样做: 画面2

是否可以使用自动布局?或者使用少量代码?

Muh*_*ati 21

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

常量约束: //这些约束在两个方向上都保持相同

1- RedView顶级空间到Superview

2- RedView尾随空间到Superview

3- BlueView超级视图的领先空间

4- BlueView底部空间到SuperView

动态约束

肖像约束:

1- RedView高度

2- RedView垂直空间到BlueView

3- RedView领先空间到Superview

4- SuperView尾随空间到Superview

LandScape约束:

1- RedView宽度

2- RedView水平空间到BlueView

3- RedView底部空间到Superview

4- BlueView顶级空间到Superview

现在您必须覆盖在方向更改时调用的方法

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)
}
Run Code Online (Sandbox Code Playgroud)

并称这两个功能

纵向定位功能

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)


}
Run Code Online (Sandbox Code Playgroud)

LandScape定位功能

    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)

}
Run Code Online (Sandbox Code Playgroud)

肖像ScreenShot: 在此输入图像描述 LandScape ScreenShot: 在此输入图像描述

希望通过编码通过布局管理帮助理解它.如果您仍然无法理解那么请检查我的代码

Github:

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

  • FIX:将高度和宽度约束优先级设置为999. (2认同)
  • 到github的链接已损坏 (2认同)

Irf*_*fan 11

iPAD没有横向模式的大小等级.我认为原因是在大多数情况下不需要它.但是,当设备方向改变时,可以激活和停用约束,如接受的答案.

以下内容对iPhone用户有所帮助.

是的,这可以在具有autolayout和size类的界面构建器中使用.您不需要编码.

首先你选择尺寸类wAny hAny

以下是如何选择尺寸等级.

在此输入图像描述

在视图控制器中添加两个视图.在上面顶视图和蓝色视图的红色视图.就像你的第一张图片一样.

红色视图的约束是:

  • 顶级空间超级观看
  • 领先的超级视野空间
  • 尾随空间到超级视图
  • 身高= 50

蓝色视图的约束是:

  • 垂直空间到红色视图
  • 超前视野的领先空间
  • 尾随空间到超级视图
  • 底层空间到超级视图

这都是为Potrait模式设置的.

现在您将大小类更改为wAny hCompact(第一行中的前两列).这个类适用于iPhone风景.

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

红色视图会改变的约束:

  • 卸载(wAny hCompact)size class的高度constriant:

在此输入图像描述

  • 类似卸载其Leading约束.在此类中为此红色视图添加两个新约束:
  • 底层空间到superview
  • 宽度约束= 50

这将使红色视图向右侧以50宽度.

现在蓝色视图的约束更改:

  • 卸载其垂直间距,尾随空格.

添加两个新约束:

  • 垂直空间到超级视图
  • 尾随空间为红色视图

这将附加蓝色视图左侧的红色视图.

希望它对你有用.


JRa*_*elM 5

我用 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];
}
Run Code Online (Sandbox Code Playgroud)

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

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


小智 3

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

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

  • 也许有人可以解释这如何回答这个问题。通读教程并下载示例,两个顶级视图会改变位置,就像 iPhone 布局问题中的位置一样,但 iPad 则不然。这正是问题所在,iPad 纵向和 iPad 横向的尺寸类别/特征是相同的。也许我错过了一些东西...... (17认同)
  • 是的,确实,单个故事板/xib 是正确的方法。但是,Apple 并不区分 iPad 纵向与横向的尺寸类别/特征。您的回答表明 iOS 11 中的情况已发生变化,但情况似乎并非如此,仍然需要使用各种解决方法来实现此行为。 (10认同)