LDOLayoutTemplates
在 Interface Builder 中设计同一视图的多个布局,并轻松在它们之间切换。
LDOLayoutTemplates 可以让您实现...
...代码量非常少
class DashboardViewController: UIViewController {
@IBOutlet weak var portraitLargeListLayout: LDOLayoutTemplate!
@IBOutlet weak var landscapeLargeListLayout: LDOLayoutTemplate!
private var defaultLayout: LDOLayoutTemplate!
private var largeListLayoutActive = false
override func viewDidLoad() {
super.viewDidLoad()
// Create a backup of the initial view contents for later restoration.
defaultLayout = LDOLayoutTemplate(withCurrentStateForViewsIn: portraitLargeListLayout)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
self.applyLayout(for: size)
})
}
@IBAction func toggleLargeListLayout() {
largeListLayoutActive.toggle()
view.layoutIfNeeded()
UIView.animate(withDuration: 0.3) {
self.applyLayout(for: self.view.bounds.size)
}
}
private func applyLayout(for size: CGSize) {
if largeListLayoutActive {
if size.width > size.height {
landscapeLargeListLayout.apply()
} else {
portraitLargeListLayout.apply()
}
} else {
defaultLayout.apply()
}
view.layoutIfNeeded()
}
}
每个视图的不同约束和属性由故事板中的三个视图定义
动机
我们喜欢在 Interface Builder 中可视地创建我们的视图。然而,如果屏幕布局在横竖屏之间不同,或者一个视图有两种模式(例如,大模式和小模式),设置约束并在代码中管理它们很快就会变成一团糟。如果你有超过两种变化,事情会更加糟糕。
如果能够分别设计每个布局,并且有一个简单的方法来切换到另一个布局,那岂不是很好?
例子
要运行示例项目,请克隆仓库,打开位于 Example
文件夹中的工作区,然后点击运行。或者,您可以使用 pod try https://github.com/lurado/LDOLayoutTemplates
。
上面的仪表板示例仅在 iPad 上可用。
如何使用
-
在场景板中,按照常规布置视图控制器视图——假设这将在横向布局中使用。
-
从库中拖动一个视图对象到左侧侧栏中的视图控制器场景,而不是其视图层次结构内。在右侧侧栏中将它的自定义类更改为
LDOLayoutTemplate
。这就是您的布局模板,在其中设计变体(例如纵向布局)。此视图永远不会显示给用户,但它的约束(和属性,见下文)将被转移到主视图。
-
将模板视图的大小更改为纵向尺寸(并非真的有必要,但这会使设计更容易)。
-
将那些在布局之间改变约束的视图从视图控制器的视图复制或重新创建到模板视图中。如果您复制了视图,请确保断开任何出口。
-
根据需要修改约束。
-
将每个模板视图的
targetView
出口与其在视图控制器视图中的相应视图连接起来。每个参与约束的模板视图都必须连接此出口。 -
在视图控制器中添加并连接一个
LDOLayoutTemplate
出口。 -
调用模板上的
apply
来切换到此布局,例如在方向改变时。如果您想要动画化过渡,请将apply
的调用包裹在一个UIView
动画块中。 -
如果您计划切换回原始布局,请创建另一个
LDOLayoutTemplate
实例(通常在viewDidLoad
中,如上面的示例代码所示)。使用LDOLayoutTemplate.init(withCurrentStateForViewsIn:)
初始化此布局,该布局基于当前的视图配置创建一个LDOLayoutTemplate
。调用此模板上的apply
以恢复视图的初始状态。 -
根据需要设置多个模板,并愉快地在它们之间切换。
属性更改
默认情况下,LDOLayoutTemplate
仅从一个视图复制自动布局约束到另一个视图。您还可以通过在Interface Builder的属性检查器中的模板属性中添加一个逗号分隔的属性列表,或通过覆盖您UIView
子类的transferredTemplateAttributeKeyPaths
,从模板中的每个视图转移到其targetView
属性。
限制
不支持布局引导,如安全区域。请使用辅助视图代替布局引导。
安装
LDOLayoutTemplates通过CocoaPods提供。要安装它,请将以下行添加到Podfile中
pod "LDOLayoutTemplates"
它是如何工作的?
这个库实际上相当简单,它采用以下方法:
- 遍历模板的所有视图,收集所有与目标视图相关的视图约束。这些约束将在调用
apply
时被激活。 - 遍历所有目标视图(在您的视图控制器视图中有指向它们的
targetView
出口的视图),并收集它们之间的所有约束。这些约束将在调用apply
时失效。 - 算法考虑了所有在设置在具有目标视图的两个视图之间,或者定义具有目标视图的视图的宽度和高度约束的约束。
作者
Raschke & Ludwig GbR, https://www.lurado.com/
许可证
LDOLayoutTemplates可供MIT许可证使用。有关更多信息,请参阅LICENSE文件。