sheet在SwiftUI中的基本用法

在 SwiftUI 中,sheet 是一个用于呈现模态视图(Modal View)的修饰器,它会在当前视图上层弹出一个新的视图。sheet 通常用于临时性任务(如登录、设置、详情展示等),用户完成操作后可以关闭它返回原视图。


基本语法

swift 复制代码
.sheet(isPresented: Binding<Bool>, onDismiss: (() -> Void)?, content: () -> View)

参数说明

参数 说明
isPresented 一个 Binding<Bool>,控制 sheet 是否显示
onDismiss 可选闭包,在 sheet 关闭时调用
content 返回要显示的视图

1. 基本使用

swift 复制代码
struct ContentView: View {
    @State private var showSheet = false

    var body: some View {
        Button("显示 Sheet") {
            showSheet.toggle() // 触发显示/隐藏
        }
        .sheet(isPresented: $showSheet) {
            Text("这是弹出的 Sheet 内容")
                .padding()
        }
    }
}

效果 :点击按钮后,从底部弹出 Text 视图,点击空白处或下滑可关闭。


2. 传递数据到 Sheet

通常结合 @State@ObservedObject 传递数据:

swift 复制代码
struct ContentView: View {
    @State private var showSheet = false
    @State private var sheetData = "Hello, Sheet!"

    var body: some View {
        Button("显示带数据的 Sheet") {
            showSheet.toggle()
        }
        .sheet(isPresented: $showSheet) {
            SheetView(data: sheetData)
        }
    }
}

struct SheetView: View {
    let data: String
    
    var body: some View {
        VStack {
            Text(data)
                .font(.title)
            Button("关闭") {
                // 通过环境变量或回调关闭
            }
        }
        .padding()
    }
}

3. 通过 item 绑定动态数据

如果 sheet 内容依赖动态数据(如从列表中选择一项),可以用 sheet(item:)

swift 复制代码
struct User: Identifiable {
    let id = UUID()
    let name: String
}

struct ContentView: View {
    @State private var selectedUser: User? // 必须是 Optional + Identifiable

    var body: some View {
        Button("显示用户 Sheet") {
            selectedUser = User(name: "张三")
        }
        .sheet(item: $selectedUser) { user in
            Text("用户名: \(user.name)")
                .padding()
        }
    }
}

说明

  • item 必须是 Optional 且符合 Identifiable,当 item 变为 nil 时,sheet 自动关闭。

4. 控制 Sheet 的关闭

方法 1:使用 presentationMode(iOS 13-15)

swift 复制代码
import SwiftUI

struct SheetView: View {
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        Button("关闭 Sheet") {
            presentationMode.wrappedValue.dismiss()
        }
    }
}

方法 2:使用 dismiss(iOS 15+)

swift 复制代码
struct SheetView: View {
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        Button("关闭 Sheet") {
            dismiss()
        }
    }
}

5. 结合 onDismiss 执行回调

swift 复制代码
struct ContentView: View {
    @State private var showSheet = false

    var body: some View {
        Button("显示 Sheet") {
            showSheet.toggle()
        }
        .sheet(isPresented: $showSheet, onDismiss: {
            print("Sheet 已关闭")
        }) {
            Text("这是 Sheet 内容")
        }
    }
}

6. 自定义 Sheet 样式

默认 sheet 是 iOS 系统样式,但可以调整:

  • 禁止下滑关闭 (iOS 16+):

    swift 复制代码
    .presentationDetents([.medium, .large])
    .interactiveDismissDisabled() // 禁止手势关闭
  • 调整高度 (iOS 16+):

    swift 复制代码
    .sheet(isPresented: $showSheet) {
        Text("半高 Sheet")
            .presentationDetents([.height(200)])
    }

常见问题

1. sheet 不显示?

  • 确保 isPresented@State@Binding
  • 确保 sheet 修饰器应用在正确的视图上。

2. 如何传递回调?

  • 使用闭包或 @Bindingsheet 能回调父视图。

3. 如何避免多次创建 sheet

  • SwiftUI 默认会缓存 sheet 内容,但复杂逻辑建议用 onAppear 优化。

总结

功能 方法
基本弹窗 .sheet(isPresented:)
动态数据弹窗 .sheet(item:)
关闭 Sheet presentationMode.dismiss()dismiss()
回调处理 onDismiss
禁止手势关闭 interactiveDismissDisabled()
调整高度 presentationDetents

sheet 是 SwiftUI 中最常用的弹窗方式,适合临时任务、表单填写等场景。

相关推荐
踩着两条虫3 分钟前
VTJ:核心引擎
前端·低代码·ai编程
GISer_Jing26 分钟前
AI时代前端开发者成长计划
前端·人工智能
方安乐28 分钟前
网页设计:自动适配浏览器深色/浅色模式
前端·html5
qq_120840937130 分钟前
Three.js 工程向:后处理性能预算与多 Pass 链路优化
前端·javascript
南棱笑笑生36 分钟前
20260422给万象奥科的开发板HD-RK3576-PI适配瑞芯微原厂的Buildroot时使用mpg123播放mp3音频
前端·javascript·音视频·rockchip
小小码农Come on1 小时前
QPainter双缓冲区实现一个简单画图软件
linux·服务器·前端
nunumaymax1 小时前
【第三章-react 应用(基于 react 脚手架)】
前端·react.js·前端框架
空中海1 小时前
第一章:Vue 基础与模板语法
前端·javascript·vue.js
每天吃饭的羊1 小时前
水平,垂直居中
前端·javascript·html
鼎道开发者联盟2 小时前
鼎享会 | OpenClaw Control UI 前端架构全解析:自研 UI 对接 Server 实操指南
前端·ui·架构·openclaw·control ui