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 中最常用的弹窗方式,适合临时任务、表单填写等场景。

相关推荐
前端加油站38 分钟前
Chrome/Firefox 浏览器扩展开发完整指南
前端·chrome
码途进化论39 分钟前
从Chrome跳转到IE浏览器的完整解决方案
前端·javascript
笙年44 分钟前
Vue 基础配置新手总结
前端·javascript·vue.js
哆啦A梦15881 小时前
40 token
前端·vue.js·node.js
炫饭第一名1 小时前
Cursor 一年深度开发实践:前端开发的效率革命🚀
前端·程序员·ai编程
摇滚侠1 小时前
Vue 项目实战《尚医通》,获取挂号医生的信息展示,笔记43
前端·javascript·vue.js·笔记·html5
晴殇i1 小时前
关于前端基础快速跨入鸿蒙HarmonyOS开发
前端·harmonyos
k09331 小时前
vue3中基于AntDesign的Form嵌套表单的校验
前端·javascript·vue.js
没头脑和不高兴y2 小时前
Element-Plus-X:基于Vue 3的AI交互组件库
前端·javascript
ErMao2 小时前
Proxy 与 Reflect:最硬核、最实用的解释
前端·javascript