介绍

import SwiftUI
struct ContentView : View {    
    var body: some View {
        Text("Hello World!")
    }
}

它的结构如下:RootView —> ContentView —> Text,那么 Text 是怎么显现在屏幕上的?官方的介绍是如下 3 个步骤。

  1. 父视图为子视图提供预估尺度。
  2. 子视图计算自己的实际尺度。
  3. 父视图依据子视图的尺度将子视图放在自身的坐标系中。

最重要的是第 2 步,一般有 3 种设置尺度的方法。

  1. 无需计算,依据内容揣度,如 Image 依据图片大小,Text 依据文字范围。
  2. 运用 frame 强制指定宽高。
  3. 设置缩放比例,如 Image 设置 aspectRatio。

frame

准备一个 100*100 的图片。

struct ContentView: View {
    var body: some View {
        Image("img")
            .border(Color.black)
            .frame(width: 200, height: 200)
            .border(Color.blue)
    }
}

SwiftUI-布局事例

只有当 frame 大于内容的尺度时,alignment 才有含义。

struct ContentView: View {
    var body: some View {
        Image("img")
            .border(Color.black)
            .frame(width: 200, height: 200, alignment: .topTrailing)
            .border(Color.blue)
    }
}

SwiftUI-布局事例

Stack

事例一

struct ContentView: View {
    var body: some View {
        HStack(spacing: 10) {
            Image("img")
            Image("img")
        }
        .frame(width: 250, height: 200)
        .border(Color.blue)
    }
}

总宽度超过 2 个 Image 和 spacing 之和,所以内容在 HStack 中正常显现。

SwiftUI-布局事例

struct ContentView: View {
    var body: some View {
        HStack(spacing: 10) {
            Image("img")
            Image("img")
        }
        .frame(width: 140, height: 200)
        .border(Color.blue)
    }
}

总宽度小于 2 个 Image 和 spacing 之和,所以内容会超出 HStack。

SwiftUI-布局事例

复杂事例

  1. 仓库计算出内部距离边距,并将其从其父视图建议的大小中减去。
  2. 关于每个剩下视图,仓库将剩下空间分红持平的部分。然后挑选其间一个作为最不灵敏的孩子,从未分配的空间中扣除其大小,然后重复该进程。
  3. 一切的孩子都有尺度以后,仓库运用距离将它们对齐,并依据指定的对齐方法将它们对齐。最终,仓库挑选自己的大小以便彻底包含子级。
struct ContentView: View {
    var body: some View {
        HStack(spacing: 10) {
            Image("img")
            Text("一切的孩子都有尺度以后,仓库运用距离将它们对齐,并依据指定的对齐方法将它们对齐。最终,仓库挑选自己的大小以便彻底包含子级。")
            Text("一切的孩子都有尺度以后,仓库运用距离将它们对齐,并依据指定的对齐方法将它们对齐。最终,仓库挑选自己的大小以便彻底包含子级。")
        }
        .padding(.horizontal, 10)
        .frame(width: 280, height: 200)
        .border(Color.blue)
    }
}
  1. 总宽度距离为 300,其距离离为 2 * 10,边距为 2 * 10,所以布局空间为:280-40 = 240。
  2. 仓库将空间分红 3 个持平的部分,每个部分的宽度为 80。
  3. 将 80 这个尺度推荐给最不灵敏的孩子。事例中为 Image,其尺度为 80×80。
  4. 仓库从剩下空间中减去 Image 的宽度,因此剩下空间为 240-80 = 160。
  5. 仓库再次将空间分红 2 个持平的部分,每个部分的宽度为 80。
  6. 它建议第 1 个 Text 的大小为 65×120。Text 回应内容不适合,但它至少可以显现一部分内容。第 2 个文本视图也是如此。因此,虽然文本视图的文本量不同,但它们的宽度都相同,都为 80。

SwiftUI-布局事例