最近遇到一个小问题,就是无法通过单一的AutoLayout来自动调整View的横屏UI,其实解决方法很简单,就是针对横屏竖屏定义两套AutoLayout,但是有时候View的嵌套比较多,这时候就很容易漏掉更新某些View的Constraint,导致UI没有正常的显示,自己暂时用下面的方法解决了一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
protocol AutoRotateView {
func setPortraitConstraints()
func setLandscapeConstraints()
func autoRotate(orientation: UIInterfaceOrientation)
}
//
extension AutoRotateView where Self: UIView{
func autoRotate(orientation: UIInterfaceOrientation) {
// make currentView to reset constraints
if (orientation == .portrait || orientation == .portraitUpsideDown) {
self.setPortraitConstraints()
}else{
self.setLandscapeConstraints()
}
}
}
//
protocol AutoRotateViewController {
func setPortraitConstraints()
func setLandscapeConstraints()
func rotateSubViews()
}
//
extension AutoRotateViewController where Self: UIViewController {
func rotateSubViews() {
// judge the target orientation
var targetOrientation: UIInterfaceOrientation!
if (UIApplication.shared.statusBarOrientation == .portrait || UIApplication.shared.statusBarOrientation == .portraitUpsideDown) {
setLandscapeConstraints()
targetOrientation = UIInterfaceOrientation.landscapeLeft
}else{
setPortraitConstraints()
targetOrientation = UIInterfaceOrientation.portrait
}
// view's subView reset Constarints
enumerateView(view, orientation: targetOrientation)
}
// reset all views in the UIViewController
func enumerateView(_ view: UIView, orientation: UIInterfaceOrientation){
for subView in view.subviews {
if let rotateView = subView as? AutoRotateView {
rotateView.autoRotate(orientation: orientation)
}
enumerateView(subView, orientation: orientation)
}
}
}

使用方法的话,对于那些需要实现横屏约束的View,实现AutoRotateView的协议,然后在View中实现setPortraitConstraintssetLandscapeConstraints的函数, 接着在需要对应横屏UI的VC中实现AutoRotateViewController的协议,同样实现协议中的方法。然后重写viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)函数,并在其中调用rotateSubViews

1
2
3
4
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
rotateSubViews()
}

等想到更好的方法后我再来更新=。=