SwiftUI 布局系统总结

16 阅读3分钟

一、基础布局容器

1. VStack(垂直排列)

  • 作用:将子视图垂直排列(从上到下)。
  • 特点:自动调整高度,支持对齐和间距控制。
  • 示例
    VStack(alignment: .leading, spacing: 10) {
        Text("标题").font(.title)
        Text("副标题").foregroundColor(.gray)
        Button("确认") { /* Action */ }
    }
    .padding()
    

2. HStack(水平排列)

  • 作用:将子视图水平排列(从左到右)。
  • 特点:自动调整宽度,常用于导航栏、按钮组。
  • 示例
    HStack(spacing: 20) {
        Image(systemName: "person.circle")
        Text("用户名:John")
        Spacer()
        Button("编辑") { /* Action */ }
    }
    .padding()
    

3. ZStack(层叠排列)

  • 作用:将子视图叠放在同一位置(类似图层)。
  • 特点:用于重叠布局(如文字+背景图)。
  • 示例
    ZStack {
        Image("background").resizable().scaledToFill()
        Text("居中文字")
            .font(.largeTitle)
            .foregroundColor(.white)
    }
    .frame(height: 200)
    

4. LazyVStack / LazyHStack(懒加载容器)

  • 作用:仅渲染可见区域的子视图,优化性能。
  • 特点:适用于长列表或动态内容。
  • 示例
    ScrollView {
        LazyVStack(spacing: 10) {
            ForEach(0..<1000) { i in
                Text("第 \(i) 行")
            }
        }
    }
    

二、列表与滚动布局

1. List(列表容器)

  • 作用:创建可滚动列表,支持分组、分隔线和动态内容。
  • 示例
    List {
        Section("设置") {
            Toggle("暗黑模式", isOn: $isDarkMode)
            Text("版本号:1.0.0")
        }
        Section("账户") {
            Button("退出登录") { /* Action */ }
        }
    }
    

2. ScrollView(滚动视图)

  • 作用:包裹内容以实现滚动效果。
  • 示例
    ScrollView(.horizontal) {
        HStack(spacing: 10) {
            ForEach(0..<20) { i in
                Image("photo\(i)").resizable().frame(width: 100, height: 100)
            }
        }
    }
    

三、网格布局

1. Grid(网格布局,iOS 16+)

  • 作用:创建灵活的行列网格。
  • 示例
    Grid(alignment: .leading) {
        GridRow {
            Text("姓名")
            Text("年龄")
            Text("职业")
        }
        Divider()
        GridRow {
            Text("John")
            Text("25")
            Text("工程师")
        }
    }
    .padding()
    

2. LazyVGrid / LazyHGrid(懒加载网格)

  • 作用:动态渲染网格内容,支持自适应列数。
  • 示例
    let columns = [GridItem(.adaptive(minimum: 100))]
    ScrollView {
        LazyVGrid(columns: columns, spacing: 10) {
            ForEach(0..<50) { i in
                Image("icon\(i)").resizable().aspectRatio(1, contentMode: .fit)
            }
        }
    }
    

四、布局辅助工具

1. Spacer(占位空间)

  • 作用:填充剩余空间,推动其他视图。
  • 示例
    HStack {
        Text("左侧")
        Spacer() // 将右侧内容推到最右
        Text("右侧")
    }
    

2. Divider(分隔线)

  • 作用:添加视觉分隔线。
  • 示例
    VStack {
        Text("第一部分")
        Divider()
        Text("第二部分")
    }
    

3. Group(逻辑分组)

  • 作用:将多个视图作为逻辑组处理(不影响布局)。
  • 示例
    VStack {
        Group {
            Text("文本1")
            Text("文本2")
        }
        .font(.headline)
    }
    

五、动态与高级布局

1. GeometryReader(几何信息读取器)

  • 作用:获取父视图的尺寸和位置信息。
  • 示例
    GeometryReader { proxy in
        Text("宽度:\(proxy.size.width)")
            .frame(width: proxy.size.width * 0.5)
    }
    

2. ViewThatFits(自适应容器,iOS 16+)

  • 作用:自动选择第一个适合屏幕的子视图。
  • 示例
    ViewThatFits {
        HStack { /* 横向布局 */ }
        VStack { /* 纵向布局 */ }
    }
    

3. AnyLayout(动态切换布局类型,iOS 16+)

  • 作用:运行时切换不同的布局容器。
  • 示例
    let layout = isVertical ? AnyLayout(VStack()) : AnyLayout(HStack())
    layout {
        Text("视图1")
        Text("视图2")
    }
    

六、布局修饰符

1. .frame(尺寸控制)

  • 示例
    Text("内容")
        .frame(width: 200, height: 100, alignment: .center)
        .background(Color.yellow)
    

2. .padding(边距控制)

  • 示例
    Text("带边距的文本")
        .padding(.horizontal, 20)
        .padding(.vertical, 10)
    

3. .offset / .position(位置调整)

  • 示例
    Text("偏移文本")
        .offset(x: 10, y: -5) // 相对位置偏移
    Text("绝对定位")
        .position(x: 100, y: 200) // 中心点绝对坐标
    

七、最佳实践总结

  1. 优先选择简单布局容器(如 VStackHStack)满足基础需求。
  2. 懒加载容器LazyVStackLazyVGrid)用于优化长列表性能。
  3. 动态布局ViewThatFitsAnyLayout)适配不同屏幕尺寸。
  4. 组合使用修饰符(如 .frame + .padding)实现精确控制。