SwiftUI 的布局系统采用声明式语法,通过嵌套的容器视图构建界面层次。布局过程是自上而下的,父视图决定子视图的可用空间,子视图决定自身尺寸。

重点:

  • Stack 容器的特性和使用场景
  • 布局修饰器的工作原理
  • GeometryReader 的作用机制
  • SafeArea 和布局适配

Stack 布局基础 Link to heading

SwiftUI 提供三种基础的 Stack 容器:

// 垂直排列
VStack(alignment: .leading, spacing: 8) {
    Text("标题")
        .font(.headline)
    Text("副标题")
        .font(.subheadline)
}

// 水平排列
HStack(spacing: 16) {
    Image(systemName: "star.fill")
    Text("评分")
    Spacer()
    Text("4.9")
}

// 重叠排列
ZStack(alignment: .topLeading) {
    Color.blue
    Text("覆盖在背景上的文字")
        .padding()
}

Stack 的关键属性:

  • alignment:对齐方式
  • spacing:元素间距
  • content:内容闭包

布局修饰器 Link to heading

frame 修饰器用于控制视图尺寸:

Text("固定宽度")
    .frame(width: 100)

Text("最大宽度")
    .frame(maxWidth: .infinity)
    .background(Color.blue)

Text("固定尺寸")
    .frame(width: 100, height: 100)
    .background(Color.gray)

padding 修饰器添加内边距:

Text("四周内边距")
    .padding()

Text("指定方向")
    .padding(.horizontal, 20)

Text("自定义边距")
    .padding([.top, .leading], 10)

GeometryReader 的使用 Link to heading

GeometryReader 提供父视图几何信息:

GeometryReader { geometry in
    HStack(spacing: 0) {
        Rectangle()
            .fill(Color.red)
            .frame(width: geometry.size.width * 0.7)
        
        Rectangle()
            .fill(Color.blue)
            // 剩余宽度自动计算
    }
}
.frame(height: 50)

常见用途:

  • 按比例分配空间
  • 响应式布局
  • 自定义布局逻辑

SafeArea 和布局适配 Link to heading

处理安全区域:

VStack {
    Text("标题")
        .frame(maxWidth: .infinity)
        .background(Color.blue)
        // 延伸到安全区域
        .ignoresSafeArea(edges: .top)
    
    ScrollView {
        // 内容
    }
}

布局优先级:

HStack {
    Text("固定宽度")
        .frame(width: 100)
        // 设置布局优先级
        .layoutPriority(1)
    
    Text("可能被截断的长文本...")
        .lineLimit(1)
}

实用布局技巧 Link to heading

  1. 使用 Spacer 灵活分配空间:
VStack {
    Text("顶部固定")
    Spacer()
    Text("底部固定")
}
  1. Group 用于布局分组:
Group {
    Text("行 1")
    Text("行 2")
    Text("行 3")
}
.font(.body)
.foregroundColor(.gray)
  1. 条件布局:
HStack {
    Text("标题")
    if showDetail {
        Text("详细信息")
    }
}

常见布局问题 Link to heading

  1. Stack 嵌套过深:
  • 影响性能
  • 增加代码复杂度
  • 建议适当拆分组件
  1. GeometryReader 使用注意:
  • 会占据父视图所有可用空间
  • 可能影响滚动行为
  • 不要过度使用
  1. 布局修饰器顺序:
// 正确:背景色填充整个区域
Text("示例")
    .padding()
    .background(Color.blue)

// 错误:背景色只填充文本区域
Text("示例")
    .background(Color.blue)
    .padding()

布局系统是 SwiftUI 的核心特性之一,掌握这些基础概念和使用技巧,能够构建出灵活且适配性强的用户界面。在实际开发中,需要根据具体场景选择合适的布局方案,并注意性能和可维护性。