我正尝试为我的模态表实现一个关闭按钮,如下所示:
struct TestView: View {
@Environment(\.isPresented) var present
var body: some View {
Button("return") {
self.present?.value = false
}
}
}
struct DataTest : View {
@State var showModal: Bool = false
var modal: some View {
TestView()
}
var body: some View {
Button("Present") {
self.showModal = true
}.sheet(isPresented: $showModal) {
self.modal
}
}
}
但是,轻按返回键不会执行任何操作。显示模态时,控制台中将显示以下内容:
[WindowServer] display_timer_callback:意外状态(现在:5fbd2efe5da4 <预期:5fbd2ff58e89)
如果您强行打开present
,您会发现它是nil
如何以编程方式关闭.sheet
?
答案 0 :(得分:9)
使用presentationMode
中的@Environment
。
测试版6
struct SomeView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
Text("Ohay!")
Button("Close") {
self.presentationMode.wrappedValue.dismiss()
}
}
}
}
答案 1 :(得分:3)
Apple 建议(在 WWDC 2020 Data Essentials in SwiftUI 中)为此使用 @State
和 @Binding
。他们还将 isEditorPresented
布尔值和工作表的数据放在使用 @State 声明的同一个 EditorConfig
结构中,以便可以对其进行变异,如下所示:
import SwiftUI
struct Item: Identifiable {
let id = UUID()
let title: String
}
struct EditorConfig {
var isEditorPresented = false
var title = ""
var needsSave = false
mutating func present() {
isEditorPresented = true
title = ""
needsSave = false
}
mutating func dismiss(save: Bool = false) {
isEditorPresented = false
needsSave = save
}
}
struct ContentView: View {
@State var items = [Item]()
@State private var editorConfig = EditorConfig()
var body: some View {
NavigationView {
Form {
ForEach(items) { item in
Text(item.title)
}
}
.navigationTitle("Items")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: presentEditor) {
Label("Add Item", systemImage: "plus")
}
}
}
.sheet(isPresented: $editorConfig.isEditorPresented, onDismiss: {
if(editorConfig.needsSave) {
items.append(Item(title: editorConfig.title))
}
}) {
EditorView(editorConfig: $editorConfig)
}
}
}
func presentEditor() {
editorConfig.present()
}
}
struct EditorView: View {
@Binding var editorConfig: EditorConfig
var body: some View {
NavigationView {
Form {
TextField("Title", text:$editorConfig.title)
}
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button(action: save) {
Text("Save")
}
.disabled(editorConfig.title.count == 0)
}
ToolbarItem(placement: .cancellationAction) {
Button(action: dismiss) {
Text("Dismiss")
}
}
}
}
}
func save() {
editorConfig.dismiss(save: true)
}
func dismiss() {
editorConfig.dismiss()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(items: [Item(title: "Banana"), Item(title: "Orange")])
}
}
答案 2 :(得分:2)
从 iOS 15 开始,我们可以使用可以作为 @Environment(\.dismiss)
访问的 DismissAction。
不再需要使用 presentationMode.wrappedValue.dismiss()
。
struct SheetView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
NavigationView {
Text("Sheet")
.toolbar {
Button("Done") {
dismiss()
}
}
}
}
}
答案 3 :(得分:1)
对我来说,Beta 4违反了此方法-使用环境变量isPresented
-使用关闭按钮。这是我现在要做的:
struct ContentView: View {
@State var showingModal = false
var body: some View {
Button(action: {
self.showingModal.toggle()
}) {
Text("Show Modal")
}
.sheet(
isPresented: $showingModal,
content: { ModalPopup(showingModal: self.$showingModal) }
)
}
}
在您的模式视图中:
struct ModalPopup : View {
@Binding var showingModal:Bool
var body: some View {
Button(action: {
self.showingModal = false
}) {
Text("Dismiss").frame(height: 60)
}
}
}