今天讨论三个SwiftUI中比较常用的Group Component,分别是Group、GroupBox和ControlGroup(这么看好像是一个😂)
Group
Group跟XStack这类组件有点类似,但它并不会对child有layout上的影响,它只是提供了一个对其内部所有child统一应用某个modifier的快捷方式
swift
Group {
Text("First")
Text("Second View")
Text("Third View")
}
.background(Color.yellow)

这样应该比较容易看得清楚。不同于VStack、HStack这类组件,他们会将modifier直接作用在stack自身上,而不是loop到内部的child身上
GroupBox
GroupBox允许开发者设置样式、组织内部child的Layout,比较常用的场景是构建Card类的UI
swift
@State private var userAgreed: Bool = false
let agreementText: String = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam fermentum vestibulum est. Cras rhoncus. Pellentesque habitant mobi tristique senectus et netus et malesuada fames ac turpis egestas."
var body: some View {
GroupBox(label: Label("End-User Agreement", systemImage: "building.columns"), content: {
Text(agreementText)
.font(.footnote)
Toggle(isOn: $userAgreed, label: {
Text("I agree to the above terms")
})
})
.groupBoxStyle(.automatic)
.padding()
}

groupBoxStyle里面也可以用自己自定义的样式,只需要继承GroupBoxStyle,func makeBody(configuration: Configuration) -> some View
方法。
swift
struct OrangeGroupBoxStyle: GroupBoxStyle {
func makeBody(configuration: Configuration) -> some View {
VStack(alignment: .leading) {
configuration.label
.font(.title)
configuration.content
}
.padding()
.background(
RoundedRectangle(cornerRadius: 5.0)
.fill(Color.orange)
.shadow(radius: 5)
)
}
}
替换 groupBoxStyle的modifier参数,效果如下

ControlGroup
常用于把类似操作功能的Component集中管理,它也会提供一些已经实现好的默认style,比如navigation、compactMenu这些
swift
ControlGroup {
Button("First"){}
Button("Second"){}
Button("Third"){}
}
ControlGroup {
Button("First"){}
Button("Second"){}
Button("Third"){}
} label: {
Label("Plus", systemImage: "plus")
}
.controlGroupStyle(.menu)
.padding()
这是一种没使用style,和一种使用了menu的style的效果


它跟GroupBox一样提供了自定义style的方式,也是继承protocol
swift
struct EqualSizeControlGroupStyle: ControlGroupStyle {
func makeBody(configuration: Configuration) -> some View {
VStack {
configuration.content
.foregroundColor(.white)
.padding(.vertical, 5)
.padding(.horizontal, 10)
.frame(maxWidth: .infinity)
.background(
RoundedRectangle(cornerRadius: 5)
.fill(Color.accentColor)
)
}
.fixedSize(horizontal: true, vertical: false)
}
}
修改controlGroupStyle这个modifier的参数,传入自己的style实例,效果如下

这个自定义的空间很大,完全取决于自己的设计了。后面有对这些组件有比较好的应用场景的例子会在补充进来