在 SwiftUI 中,ZStack
是一个布局容器,用于 将子视图沿 Z 轴(垂直于屏幕方向)层叠排列 ,使它们按照声明顺序从后向前堆叠。以下是关于 ZStack
的全面解析和实际应用指南:
1. 基本语法
swift
ZStack {
View1() // 最底层
View2() // 中间层
View3() // 最上层
}
- 默认行为 :
子视图按代码顺序从后向前排列(最后一个视图在最上层)。
2. 核心功能
(1)基础层叠
swift
ZStack {
Circle().fill(Color.red).frame(width: 100, height: 100)
Circle().fill(Color.blue).frame(width: 80, height: 80)
Circle().fill(Color.green).frame(width: 60, height: 60)
}
效果 :
绿色圆形在最上层,蓝色居中,红色在最底层。
(2)对齐方式控制
通过 alignment
参数调整所有子视图的对齐基准点:
swift
ZStack(alignment: .topLeading) { // 左上角对齐
Rectangle().fill(Color.gray).frame(width: 200, height: 200)
Text("Hello").padding()
}
支持的对齐方式(Alignment
):
枚举值 | 描述 |
---|---|
.center |
中心对齐(默认) |
.topLeading |
左上角对齐 |
.bottomTrailing |
右下角对齐 |
其他组合 | 如 .topTrailing |
3. 实际应用场景
场景 1:图片文字叠加
swift
ZStack {
Image("Background")
.resizable()
.aspectRatio(contentMode: .fill)
Text("欢迎使用")
.font(.largeTitle)
.foregroundColor(.white)
.shadow(radius: 5)
}
.frame(height: 300)
.clipped() // 裁剪超出部分
场景 2:悬浮按钮
swift
ZStack(alignment: .bottomTrailing) {
ScrollView {
// 主内容列表...
}
Button(action: {}) {
Image(systemName: "plus")
.padding()
.background(Circle().fill(Color.blue))
}
.padding()
}
场景 3:进度条覆盖
swift
ZStack {
Rectangle() // 背景条
.fill(Color.gray.opacity(0.3))
.frame(height: 10)
Rectangle() // 进度条
.fill(Color.blue)
.frame(width: progress * 200, height: 10)
.frame(maxWidth: .infinity, alignment: .leading) // 左对齐
}
.frame(width: 200)
4. 高级技巧
(1)动态控制层叠顺序
通过 zIndex
覆盖默认的声明顺序:
swift
ZStack {
ViewA().zIndex(1) // 强制置顶
ViewB().zIndex(0) // 即使后声明,也会在下方
}
(2)与 overlay
和 background
的关系
ZStack
是显式的多层容器,适合复杂层叠。overlay
和background
是隐式的单层附加视图,适合简单装饰。
(3)性能优化
对大量动态层叠视图(如游戏界面),建议:
- 使用
Group
分组静态元素。 - 对动画视图应用
.drawingGroup()
启用 GPU 加速。
5. 完整代码示例
可拖拽卡片层叠
swift
struct CardStack: View {
@State private var cards = [
Card(color: .red, offset: CGSize.zero),
Card(color: .blue, offset: CGSize.zero)
]
var body: some View {
ZStack {
ForEach(cards.indices, id: \.self) { index in
RoundedRectangle(cornerRadius: 10)
.fill(cards[index].color)
.frame(width: 200, height: 150)
.offset(cards[index].offset)
.gesture(
DragGesture()
.onChanged { value in
cards[index].offset = value.translation
}
.onEnded { _ in
withAnimation(.spring()) {
cards[index].offset = .zero
}
}
)
.zIndex(cards[index].offset == .zero ? 0 : 1) // 拖拽时置顶
}
}
}
}
struct Card {
let color: Color
var offset: CGSize
}
6. 与其他容器对比
容器 | 作用 | 与 ZStack 的区别 |
---|---|---|
VStack |
垂直排列 | 沿 Y 轴排列 |
HStack |
水平排列 | 沿 X 轴排列 |
Grid |
网格排列 | 二维布局 |
总结
功能 | 代码示例 |
---|---|
基础层叠 | ZStack { View1(); View2() } |
对齐控制 | ZStack(alignment: .topLeading) { ... } |
动态排序 | .zIndex(1) |
悬浮元素 | ZStack(alignment: .bottom) { ScrollView; Button } |
核心用途 :
✅ 创建重叠式布局(如卡片、模态弹窗)
✅ 实现视觉层次(文字+背景图组合)
✅ 构建交互式组件(如拖拽排序、游戏场景)
掌握 ZStack
可以轻松实现复杂的界面层叠效果! 🎨