Zstack垂直排列基本用法

在 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)与 overlaybackground 的关系

  • ZStack 是显式的多层容器,适合复杂层叠
  • overlaybackground 是隐式的单层附加视图,适合简单装饰

(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 可以轻松实现复杂的界面层叠效果! 🎨

相关推荐
OpenTiny社区1 分钟前
把 SearchBox 塞进项目,搜索转化率怒涨 400%?
前端·vue.js·github
编程猪猪侠31 分钟前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞34 分钟前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路1 小时前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失9491 小时前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue8681 小时前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
UncleKyrie1 小时前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端
遂心_1 小时前
深入解析前后端分离中的 /api 设计:从路由到代理的完整指南
前端·javascript·api
你听得到111 小时前
Flutter - 手搓一个日历组件,集成单日选择、日期范围选择、国际化、农历和节气显示
前端·flutter·架构
风清云淡_A1 小时前
【REACT18.x】CRA+TS+ANTD5.X封装自定义的hooks复用业务功能
前端·react.js