本篇目标

掌握 SwiftUI 的布局系统,理解 VStack、HStack、ZStack 的使用方式,学会使用 Spacer、padding、frame、对齐方式构建常见界面布局。

一、布局基础

SwiftUI 的布局是声明式的:你描述视图应该如何排列,系统自动计算位置和尺寸。

三种基础布局容器:

容器

方向

说明

VStack

垂直

从上到下排列

HStack

水平

从左到右排列

ZStack

叠层

前后叠加

二、VStack 垂直布局

VStack {
    Text("第一行")
    Text("第二行")
    Text("第三行")
}

设置间距:

VStack(spacing: 20) {
    Text("第一行")
    Text("第二行")
}

设置对齐方式:

VStack(alignment: .leading) {
    Text("左对齐")
    Text("第二行")
}

常用对齐:

  • .leading:左对齐

  • .center:居中(默认)

  • .trailing:右对齐

三、HStack 水平布局

HStack {
    Image(systemName: "star.fill")
    Text("收藏")
}

设置间距:

HStack(spacing: 12) {
    Image(systemName: "star.fill")
    Text("收藏")
}

设置对齐方式:

HStack(alignment: .top) {
    Image(systemName: "star.fill")
    Text("多行文字\n第二行")
}

常用对齐:

  • .top:顶部对齐

  • .center:垂直居中(默认)

  • .bottom:底部对齐

  • .firstTextBaseline:第一行文字基线对齐

四、ZStack 叠层布局

ZStack {
    Color.blue
    Text("Hello")
        .foregroundColor(.white)
}
.frame(width: 200, height: 100)

对齐方式:

ZStack(alignment: .topLeading) {
    Color.blue
    Text("左上角")
        .foregroundColor(.white)
}
.frame(width: 200, height: 100)

常用对齐:

  • .topLeading:左上

  • .top:上中

  • .topTrailing:右上

  • .leading:左中

  • .center:居中(默认)

  • .trailing:右中

  • .bottomLeading:左下

  • .bottom:下中

  • .bottomTrailing:右下

五、Spacer

Spacer 用于填充剩余空间,把视图推到一边。

HStack {
    Text("左边")
    Spacer()
    Text("右边")
}

设置最小长度:

Spacer(minLength: 20)

在 VStack 中:

VStack {
    Text("顶部")
    Spacer()
    Text("底部")
}
.frame(height: 200)

六、padding

padding 用于添加内边距。

四边相同:

Text("Hello")
    .padding()

指定数值:

Text("Hello")
    .padding(20)

指定方向:

Text("Hello")
    .padding(.horizontal, 20)
    .padding(.vertical, 10)

指定单边:

Text("Hello")
    .padding(.top, 10)
    .padding(.leading, 20)

常用方向:

  • .all:四边

  • .horizontal:水平

  • .vertical:垂直

  • .top、.bottom、.leading、.trailing

七、frame

frame 用于设置视图的尺寸。

固定尺寸:

Text("Hello")
    .frame(width: 200, height: 100)

最大宽度:

Text("Hello")
    .frame(maxWidth: .infinity)

最大高度:

Text("Hello")
    .frame(maxHeight: .infinity)

对齐方式:

Text("Hello")
    .frame(width: 200, height: 100, alignment: .leading)

常用组合:

Text("Hello")
    .frame(maxWidth: .infinity, alignment: .leading)
    .padding()

八、布局优先级

用 layoutPriority 控制空间分配优先级。

HStack {
    Text("短文本")
    Text("这是一段很长的文本,需要更多空间")
        .layoutPriority(1)
}

说明:

  • 数值越大,优先级越高。

  • 默认优先级为 0。

九、常见布局组合

卡片布局

VStack(alignment: .leading, spacing: 8) {
    Image(systemName: "photo")
        .font(.largeTitle)
        .foregroundColor(.blue)
    Text("标题")
        .font(.headline)
    Text("描述文字")
        .font(.subheadline)
        .foregroundColor(.gray)
}
.padding()
.background(Color(.systemGray6))
.cornerRadius(12)

列表行布局

HStack {
    Image(systemName: "person.circle")
        .font(.largeTitle)
    VStack(alignment: .leading) {
        Text("姓名")
            .font(.headline)
        Text("描述")
            .font(.subheadline)
            .foregroundColor(.gray)
    }
    Spacer()
    Image(systemName: "chevron.right")
        .foregroundColor(.gray)
}
.padding()

顶部栏布局

HStack {
    Button("返回") {
        // 返回操作
    }
    Spacer()
    Text("标题")
        .font(.headline)
    Spacer()
    Button("更多") {
        // 更多操作
    }
}
.padding()

十、避坑指南

  • 修饰符顺序:.padding().background() 和 .background().padding() 效果不同。

  • Spacer 需要父容器有空间:在无限空间中 Spacer 可能不生效。

  • frame 设置过大:可能导致布局溢出。

  • 嵌套过深:影响可读性和性能,适当提取子视图。

  • 对齐方式不要混用:VStack 用水平对齐,HStack 用垂直对齐。

  • 预览多设备:注意小屏和大屏的适配。

十一、检查清单

  • [ ] 掌握 VStack、HStack、ZStack

  • [ ] 会使用 Spacer 推挤视图

  • [ ] 会使用 padding 控制内边距

  • [ ] 会使用 frame 控制尺寸

  • [ ] 理解布局优先级

  • [ ] 能组合常见布局(卡片、列表行、顶部栏)

  • [ ] 能处理简单适配问题