文章目录
- 1、核心方法 viewWillTransition
- 2、如何在横竖屏切换时更改 UI 细节?
- 3、后续问题发现
- (1) 如果在两个类中使用 viewWillTransition 不起作用
- (2) 如何让某个 ViewController 保持竖屏?
1、核心方法 viewWillTransition
/// 切换横竖屏时,重设子view布局
public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
...
}
- 判断横竖屏方式一:
if size.width > size.height { /// 横屏
...
} else { /// 竖屏
...
}
- 判断横竖屏方式二:
let orientation = UIApplication.shared.statusBarOrientation
switch orientation {
case .portrait, .portraitUpsideDown, .unknown: /// 竖屏
...
case .landscapeLeft, .landscapeRight: /// 横屏
...
}
2、如何在横竖屏切换时更改 UI 细节?
- 以弹窗为例,UI 细节有:横屏居中显示,竖屏底部显示;弹窗高度,字体大小,UIView 的大小及 Offset。
- (1)约束方式:
重点:remakeConstraints
public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
...
container.snp.remakeConstraints { make in
switch style {
case .horizontal:
make.center.equalToSuperview()
make.width.equalTo(config.containerWidth)
case .vertical:
make.bottom.equalTo(view.snp.bottom)
make.leading.trailing.equalToSuperview()
}
make.height.equalTo(config.containerHeight)
}
...
}
- UIView 的宽高:
/// 定义
private var closeViewTopMargin: Constraint?
private var closeViewRightMargin: Constraint?
private var closeViewSize: Constraint?
/// 赋值
closeView.snp.makeConstraints { make in
self.closeViewTopMargin = make.top.equalTo(background).offset(config.closeViewTopRightMargin).constraint
self.closeViewRightMargin = make.trailing.equalTo(background).offset(-config.closeViewTopRightMargin).constraint
self.closeViewSize = make.width.height.equalTo(config.closeViewSize).constraint
}
/// 更新
public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
...
self.closeViewTopMargin?.update(offset: config.closeViewTopRightMargin)
self.closeViewRightMargin?.update(offset: -config.closeViewTopRightMargin)
self.closeViewSize?.update(offset: config.closeViewSize)
...
}
3、后续问题发现
(1) 如果在两个类中使用 viewWillTransition 不起作用
- 原因:当前的 ViewController 中复写了 viewWillTransition 方法,如果没有调用 super 方法,此消息不会再传递到下一个 ViewController 中。
- 解决方法:
public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
...
}
- 参考资料:http:///iOS/
(2) 如何让某个 ViewController 保持竖屏?
-
代码实现:
-
AppDelegate:
/// 全局变量
var isAllowAutorotate: Bool = true
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
...
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?)
-> UIInterfaceOrientationMask {
if isAllowAutorotate {
return [.portrait, .landscapeLeft, .landscapeRight]
}
else {
return .portrait
}
}
...
}
- 想要保持竖屏的 ViewController:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
isAllowAutorotate = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
isAllowAutorotate = true
}
- 参考资料:/p/816d024a4c6f?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation