在 SwiftUI 中,.sheet
是一个 视图修饰符(View Modifier) ,用于模态呈现(Modal Presentation)一个新的视图(通常是从底部滑出的卡片式界面)。它类似于 UIKit 中的 present(_:animated:completion:)
。
基本语法
swift
.sheet(
isPresented: Binding<Bool>, // 控制是否显示
onDismiss: (() -> Void)? = nil, // 关闭时的回调
content: () -> Content // 要显示的视图
)
参数说明
参数 | 类型 | 说明 |
---|---|---|
isPresented |
Binding<Bool> |
控制 sheet 是否显示(true 显示,false 隐藏) |
onDismiss |
(() -> Void)? |
当 sheet 关闭时触发的回调(可选) |
content |
() -> Content |
返回要显示的视图(闭包) |
基本使用示例
1. 显示一个简单 Sheet
swift
struct ContentView: View {
@State private var isShowingSheet = false
var body: some View {
Button("Show Sheet") {
isShowingSheet = true
}
.sheet(isPresented: $isShowingSheet) {
Text("This is a Sheet!")
.padding()
}
}
}
效果 :点击按钮后,从底部弹出 Text("This is a Sheet!")
。
2. 传递数据并自定义 Sheet 内容
swift
struct ContentView: View {
@State private var isShowingSheet = false
@State private var userName = ""
var body: some View {
VStack {
TextField("Enter your name", text: $userName)
Button("Show Greeting Sheet") {
isShowingSheet = true
}
}
.sheet(isPresented: $isShowingSheet) {
GreetingView(name: userName)
}
}
}
struct GreetingView: View {
let name: String
var body: some View {
VStack {
Text("Hello, \(name)!")
Button("Dismiss") {
// 如何关闭?👉 需要传递 Binding 或使用 @Environment(\.dismiss)
}
}
}
}
问题 :GreetingView
如何关闭自己?👉 可以使用 @Environment(\.dismiss)
。
3. 在 Sheet 内部关闭自己(iOS 15+)
swift
import SwiftUI
struct GreetingView: View {
@Environment(\.dismiss) var dismiss // 获取 dismiss 方法
let name: String
var body: some View {
VStack {
Text("Hello, \(name)!")
Button("Dismiss") {
dismiss() // 关闭当前 Sheet
}
}
}
}
说明:
@Environment(\.dismiss)
是 SwiftUI 提供的一个环境变量,用于关闭当前模态视图(sheet
、fullScreenCover
等)。- 适用于 iOS 15+ ,在旧版本中需要使用
@Binding
控制关闭。
4. 旧版本(iOS 13-14)使用 @Binding
关闭
swift
struct ContentView: View {
@State private var isShowingSheet = false
var body: some View {
Button("Show Sheet") {
isShowingSheet = true
}
.sheet(isPresented: $isShowingSheet) {
SheetView(isPresented: $isShowingSheet)
}
}
}
struct SheetView: View {
@Binding var isPresented: Bool
var body: some View {
Button("Close") {
isPresented = false // 手动关闭
}
}
}
适用场景:兼容 iOS 13-14 的代码。
.sheet
vs .fullScreenCover
特性 | .sheet |
.fullScreenCover |
---|---|---|
显示方式 | 从底部滑出(卡片式) | 全屏覆盖 |
手势关闭 | 支持下滑关闭 | 默认不能手势关闭 |
适用场景 | 临时输入、简短信息 | 全屏内容(如登录页) |
.fullScreenCover
示例
swift
.fullScreenCover(isPresented: $isShowingFullScreen) {
FullScreenView()
}
总结
.sheet
用于 模态显示一个非全屏视图(通常从底部滑出)。- 使用
@Environment(\.dismiss)
(iOS 15+)或@Binding
(iOS 13-14)关闭。 - 适用于 临时弹窗、表单输入、二级内容展示 等场景。
希望这个指南对你有帮助!🚀