使用 SwiftUI 的 GroupBox 组件简化布局

了解如何使用 GroupBox 组件,更轻松的创建容器视图,避免复杂的 Stack 嵌套。

使用 SwiftUI 的 GroupBox 组件简化布局
💡
本文持续更新中~

什么是 GroupBox

GroupBox 是 iOS14 开始引入的组件。

在移动应用 UI 设计中,我们经常需要创建类似于这样的布局:

通常,你可以使用 VStack 和 HStack 的嵌套来实现这样的效果,例如:

VStack(alignment: .leading, spacing: 10) {
    Text("标题")
        .font(.headline)
    
    VStack(alignment: .leading, spacing: 5) {
        Text("第一行内容")
        Text("第二行内容")
    }
    .padding()
    .background(Color.gray.opacity(0.1))
    .cornerRadius(8)
}
.padding()

使用 GroupBox,上述布局可以显著简化,且代码更清晰易读:

GroupBox(label: Label("标题", systemImage: "info.circle")) {
    VStack(alignment: .leading, spacing: 5) {
        Text("第一行内容")
        Text("第二行内容")
    }
}
.padding()

GroupBox 也可以不使用 Label 标签,例如下面这种场景:

var body: some View {
    GroupBox {
        HStack {
            StatisticItem(
                title: "待开票",
                value: "\(pendingInvoiceCount)笔",
                color: .blue
            )
            StatisticItem(
                title: "待报销",
                value: "\(pendingReimbursementCount)笔",
                color: .orange
            )
            StatisticItem(
                title: "待报销金额",
                value: String(format: "%.0f元", pendingAmount),
                color: .purple
            )
        }
        .padding(.vertical, 8)
    }
}

自定义样式

修改 GroupBox 背景颜色

使用 .backgroundStyle 修改 GroupBox 的背景色,而不是 .backgroundColor,后者无法生效:

GroupBox {
    Text("自定义内容")
}
.backgroundStyle(.purple)

修改 GroupBox 固定高度

GroupBox 不支持通过.frame()修饰器来固定高度,下面这种用法不会生效:

GroupBox {
  HStack {
    Text("自定义内容")
    Text("自定义内容")
  }
}
.frame(height: 140) // 设置固定高度

一种替代方案是,在 GroupBox 内部组件上设置 .frame,例如:

GroupBox {
  HStack {
    Text("自定义内容")
    Text("自定义内容")
  }
  .frame(height: 140) // 设置固定高度
}