Swiftui 快速解雇单

Swiftui 快速解雇单,swiftui,Swiftui,我正在尝试为我的模式表实现一个dismise按钮,如下所示: struct TestView: View { @Environment(\.isPresented) var present var body: some View { Button("return") { self.present?.value = false } } } struct DataTest : View { @State var

我正在尝试为我的模式表实现一个dismise按钮,如下所示:

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
        }
    }
}
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")])
    }
}
但点击返回按钮时,什么也不做。当显示模式时,控制台中将显示以下内容:

[WindowsServer]显示\计时器\回调:意外状态(现在:5fbd2efe5da4<预期:5fbd2ff58e89)

如果强制展开
present
,您会发现它是
nil


如何以编程方式关闭
.sheet

对于我来说,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)
        }
    }
}

使用
@环境中的
presentationMode

β6

苹果建议(in)为此使用
@State
@Binding
。它们还将
isEditorPresented
布尔值和工作表的数据放在使用@State声明的同一
EditorConfig
结构中,以便对其进行变异,如下所示:

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
        }
    }
}
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")])
    }
}
iOS 15 从iOS 15开始,我们可以使用可作为
@Environment(\.disease)
访问的

不再需要使用
presentationMode.wrappedValue.dismise()


是的,这是目前唯一的出路。isPresented仅在您将其与不推荐使用的PresentationLink一起使用时有效,但仅在它未用作导航栏项时有效。@Marc_T.,我之前在这里提到过一次,答复与我一样令人沮丧-为什么要更改?(我显然不是快速发展的一部分——希望我说的没错。)Beta 2==
PresentationButton
。Beta 3==
PresentationLink
。Beta 4==嗯,对不起,这都是不推荐的,而且“你完蛋了”?你知道为什么会发生这种事情吗?相信我,我理解贝塔。请理解,我们也在谈论第一版,如
Swift 1.0
。也许我对这种事情背后的政治有点天真,但我很聪明。我很想知道发生了什么事,没用。请您解释更多或添加更多代码。两种解除工作表的方法(此方法和注入isShowing绑定)的一个恼人之处是,当您点击解除按钮时,不会触发工作表方法的
onDismiss
关闭。但如果用户通过向下滑动解除模式,它将触发。这可能会引起苹果的不满。不幸的是,这似乎不适用于macOS导航视图,因为列表和视图同时显示。任何已知的方法?由于
presentationMode
是绑定的路径,因此实际上可以将
@binding
嵌套在
@Environment
中,以摆脱
.wrappedValue
部分。