Ios XCode:如何在横向和纵向模式之间更改视图布局
在纵向模式下,我有四个视图,从视图控制器的顶部到底部,彼此重叠(见图) 然后,当设备转换到横向时,我想改变视图相对于彼此的位置(参见图2) 我希望视图4与视图2和3并排移动,它们都位于视图1下方 一些布局条件:Ios XCode:如何在横向和纵向模式之间更改视图布局,ios,swift,xcode,Ios,Swift,Xcode,在纵向模式下,我有四个视图,从视图控制器的顶部到底部,彼此重叠(见图) 然后,当设备转换到横向时,我想改变视图相对于彼此的位置(参见图2) 我希望视图4与视图2和3并排移动,它们都位于视图1下方 一些布局条件: 视图1在横向和纵向上都附着到视图控制器的顶部 在纵向模式下,视图4附着到视图控制器的左、右和下边距 视图2、3和4在纵向视图中水平居中 实现不同布局的最佳方法是什么 最优雅的解决方案是引用视图控制器代码中的约束,并在viewWillTransition中激活和停用它们吗?或者有没有
- 视图1在横向和纵向上都附着到视图控制器的顶部
- 在纵向模式下,视图4附着到视图控制器的左、右和下边距
- 视图2、3和4在纵向视图中水平居中
最优雅的解决方案是引用视图控制器代码中的约束,并在viewWillTransition中激活和停用它们吗?或者有没有一种方法可以使用vary for traits来实现这一点(我可以想象视图2、3和4水平居中会使这一点很难实现,并且在横向模式下为视图4添加新的约束)?我使用约束数组,并根据方向激活/取消激活
var p = [NSLayoutConstraint]()
var l = [NSLayoutConstraint]()
var initialOrientation = true
var isInPortrait = false
override func viewDidLoad() {
super.viewDidLoad()
// add any subviews here
view.turnOffAutoResizing()
// add constraints here....
// common constraints you can set their isActive = true
// otherwise, add in to portrait(p) and landscape(l) arrays
}
override func viewWillLayoutSubviews() {
super.viewDidLayoutSubviews()
if initialOrientation {
initialOrientation = false
if view.frame.width > view.frame.height {
isInPortrait = false
} else {
isInPortrait = true
}
view.setOrientation(p, l)
} else {
if view.orientationHasChanged(&isInPortrait) {
view.setOrientation(p, l)
}
}
}
extension UIView {
public func turnOffAutoResizing() {
self.translatesAutoresizingMaskIntoConstraints = false
for view in self.subviews as [UIView] {
view.translatesAutoresizingMaskIntoConstraints = false
}
}
public func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool {
if self.frame.width > self.frame.height {
if isInPortrait {
isInPortrait = false
return true
}
} else {
if !isInPortrait {
isInPortrait = true
return true
}
}
return false
}
public func setOrientation(_ p:[NSLayoutConstraint], _ l:[NSLayoutConstraint]) {
NSLayoutConstraint.deactivate(l)
NSLayoutConstraint.deactivate(p)
if self.bounds.width > self.bounds.height {
NSLayoutConstraint.activate(l)
} else {
NSLayoutConstraint.activate(p)
}
}
}
我需要区分纵向和横向需要使用尺寸等级以外的东西,因为我的应用程序是通用的,iPad(除非使用拆分视图或滑出视图)总是正常尺寸。此外,您可以使用
viewWillTransistion(toSize:)
或viewDidLoadSubviews()
而不是“viewWillLoadSubviews()”—但请始终进行测试,因为这些操作可能会在方向更改时执行多次 我们过去常常设置不同的约束集,并根据方向变化激活/停用它们。但如今,我们可以使用尺码等级和“不同的特征”
例如,我从一个简单的视图开始,选择一个紧凑的宽度大小类,然后选择“根据特征变化”:
然后,我添加适当的约束并单击“完成”:
然后,我选择一个“常规宽度大小类”,并重复该过程(“改变特征”,添加约束,单击“完成改变”:
然后,您将看到一个场景,该场景将具有一组完全不同的约束,用于紧凑宽度大小类和常规宽度大小类。例如,当我运行应用程序时,如果设备旋转,则会激活新的约束:
有关更多信息,请参阅WWDC 2016自适应布局视频: