SwiftUI内功之深入研究布局

视图布局的任务是为视图树中的每个视图分配位置和大小。在SwiftUI中,实现布局的算法原则上很简单:

对于层次结构中的每个视图,SwiftUI都会建议一个大小(可用空间)。视图将自己布置在该可用空间内,并以其实际大小进行报告。然后,系统(默认情况下)将视图置于可用空间的中心。尽管没有可用的公共API,请想象每个View都实现了以下方法:

struct ProposedSize {
    var width, height: CGFloat?
}
extension View {
    func layout(in: ProposedSize) -> CGSize {
        // ...
        for child in children {
            child.layout(in: ...)
        }
        // ...
    }
}

为了解释各个视图的布局行为,我们假设存在上述方法

在SwiftUI中,使布局变得复杂的原因是,从建议的尺寸确定实际尺寸时,每个视图(或视图修改器)的行为都不同。例如,形状总是适合自己的建议尺寸;

  • HStack采用其子级所需的尺寸(不超过建议的尺寸);
  • Text采用呈现文本所需的大小,除非其大小超过建议的大小,在这种情况下,文本将被剪切。

通常,建议尺寸的两个尺寸都将为非零值。 nil值表示视图可以在该维度上变为理想​​大小。虽然布局过程会为每个视图(即矩形)分配尺寸和位置,但视图并不总是在这些范围内绘制自身。这在动画处理中尤其有用:我们可能希望保持视图的布局位置(以便其他视图也保持在原位),但以偏移或旋转的方式绘制视图

在本章的其余部分,我们将探讨SwiftUI的布局过程。我们将从一些基本视图的布局行为开始,例如“Text”和“Image”。然后,我们来看几个布局修改器,例如.frame和.offset。最后,我们将讨论堆栈视图。

基本视图

让我们更详细地了解一些常用视图的布局行为:Shape,Image和Text。由于未记录SwiftUI视图的确切布局行为,因此我们必须通过实验来确定。一种简单的方法是将任何视图包装在框架中。框架大小由两个滑块控制,因此易于实验。


Jietu20200311-225358.gif
struct ContentView: View {
    @State private var width: CGFloat = 100
       @State private var height: CGFloat = 100
    var body: some View {
        VStack {
                  Text("hello")
                       .border(Color.gray)
                       .frame(width: width, height: height)
                       .border(Color.black)
            
                   Slider(value: $width, in: 0...500)
                   Slider(value: $height, in: 0...200)
                   
               }
    }
}
}

你可能感兴趣的:(SwiftUI内功之深入研究布局)