[英]Different View/Layout for Landscape Orientation
我正在构建一个计算器应用程序并让它在纵向模式下工作。 但是,我希望用户在切换到横向模式时有更多选项/功能。 换句话说,整个布局必须改变,因为与纵向模式相比,横向模式会有更多的按钮。
我已经使用属性检查器下的installed
属性设法做到了这一点。 以下是我遇到的问题:
我究竟做错了什么? 我该如何解决这个问题?
这是我自 iOS9 以来一直在做的事情。 完整代码,您使用的IB不承担(其实我觉得你不应该),并应帮助你自动布局是如何工作的。 当心,这确实需要一些自动布局和 Swift 的知识。 这也涉及一个非常简单的UIButton
示例。
首先,声明两个约束数组,通常在视图控制器中:
var landscape = [NSLayoutConstraint]()
var portrait = [NSLayoutConstraint]()
var myButton = UIButton()
接下来,设置常量约束并设置活动:
myButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myButton)
myButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
myButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
myButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
到现在为止还挺好。 您已经创建了一个按钮,将其添加到 VC 视图中,并声明其大小为 40x200。 您还声明它锚定到父级的safeAreaLayoutGuide
顶部锚点。
现在,是时候发挥“魔法”了。 您希望根据方向将此UIButton
从底部向右移动。 (请注意,虽然某些覆盖可以在 iPhone 上运行,但在全屏时 iPad 将始终具有“常规”尺寸类别 - 全屏 - 无论方向如何!)
您需要做的第一件事是将剩余的约束放入您声明的数组中。
portrait.append(myButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10))
landscape.append(myButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10))
现在您需要激活单个约束。 可以更多,记住我们说的是数组。 这很简单,只需根据需要停用和激活:
func changeConstraints() {
if isInPortrait {
NSLayoutConstraint.deactivate(landscape)
NSLayoutConstraint.activate(portrait)
} else {
NSLayoutConstraint.deactivate(portrait)
NSLayoutConstraint.activate(landscape)
}
}
您甚至可以根据自己的意愿为事物设置动画! 最后,让我们进入 VC 生命周期。 我很确定还有其他(和更好的)方法,但请记住我之前提到的 - 在全屏模式下,iPad 将始终具有常规尺寸等级。 所以我更喜欢深入挖掘。 我倾向于使用三个变量——你可能需要的更少。
var initialOrientation = true
var isInPortrait = false
var orientationDidChange = false
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if initialOrientation {
initialOrientation = false
if view.frame.width > view.frame.height {
isInPortrait = false
} else {
isInPortrait = true
}
changeConstraints()
} else {
if view.orientationHasChanged(&isInPortrait) {
changeConstraints()
}
}
}
我也有UIView
的扩展:
extension UIView {
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
}
}
我认为这应该描述我的大部分代码。 基本上,(a)不使用UIDevice
或 (b) 使用viewWillTransition(toSize:)
并在使用 iPad 时检查大小类。 (它们将有一个尺寸等级变化 - 尽管根据尺寸在设备上有所不同,但仅限于在分屏模式下。至少现在!)
view willLayoutSubviews
,使用 (a) view willLayoutSubviews
- 你可以使用view DidLayoutSubviews
但我更喜欢尽早做事 - 然后 (b) 检查实际屏幕尺寸。
您可以在视图控制器类生命周期中使用 iOS 方向更改方法。
首先,您必须使用 stackViews 和视图 UI 对象制作所有适当的 UI。
然后,您需要使用 iOS 大小类来管理您的约束(宽度、高度、计算器 UI 按钮/视图的比率。
还要在您的视图控制器中添加此方法并管理您的视图可见性
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("Landscape")
// Show your additional UIs elements views for Landscape
} else {
print("Portrait")
// Hide your additional UIs elements / views for Portrait
}
}
如果您在制作 UI 尺寸方面需要任何帮助,请按照以下选项进行操作。 所以你必须使用 iOS 大小类。
有用的网址:
https://medium.com/swlh/ios-adaptive-layout-i-size-class-c561bd730e1 https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and -布局/
我为您制作了一个示例工作并添加到我的 GitHub 存储库中。
请查看 main.storyboard UI 设置并完成您的工作。
回购: https : //github.com/ryra-circuit/DynamicUICalculator
谢谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.