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

相关推荐
鲤鱼_5991 小时前
记录——前端开发IDEA需要的插件
前端
摘星编程1 小时前
基于 JiuwenSwarm AgentTeam 构建混沌工程自动化实战
前端·chrome
nashane1 小时前
HarmonyOS 6学习:Web组件与JavaScript交互的三大高频问题与终极解决方案
前端·学习·harmonyos
顾随1 小时前
(2)达梦数据库--SQl基础实践
前端·数据库·sql
键盘飞行员1 小时前
Windsurf + Claude 4.7 前端开发:用 ui-ux-pro-max 根治 “AI 味”、实现全站 UI 统一
前端·ui·ai编程
IT_陈寒1 小时前
被JavaScript的隐式类型转换坑到怀疑人生,记录这次离谱经历
前端·人工智能·后端
梦无矶1 小时前
快速设置npm默认源为国内全局镜像源
前端·npm·node.js
aichitang20242 小时前
HTML 实时预览工具
前端·html
广州智维科技2 小时前
Kvaser Edge WL400S:工业级边缘计算与 CAN‑FD 数据采集平台解析73-30130-01688-0
前端·edge·边缘计算
吃好睡好便好2 小时前
在Matlab中用sphere( )函数绘制球面图
开发语言·前端·javascript·学习·算法·matlab·信息可视化