英文:
SwiftUI using ObservableObject with Binding cause sheet crash
问题
Root:
class Benef: ObservableObject {
@Published var val: String = ""
}
@main
struct TestApp: App {
@StateObject var beenf = Benef()
var body: some Scene {
WindowGroup {
ContentView(testt: $beenf.val)
}
}
}
ContentView:
enum Test: Identifiable {
case one
case two
var id: String {
switch self {
case .one : return "One"
case .two : return "Two"
}
}
}
struct ContentView: View {
@Environment(\.dismiss) private var dismiss
@State private var showingFirst: Test?
@State private var showingSecond: Test?
@Binding var testt: String
var body: some View {
VStack {
Button("Show First Sheet") {
showingFirst = .one
}
}
.sheet(item: $showingFirst) { tt in
FirstSheetiew {
showingSecond = .two
}
}
.sheet(item: $showingSecond) { tt in
VStack {
Text("Second Sheet")
Button("Dismiss") {
dismiss()
}
}
}
}
}
struct FirstSheetiew: View {
@Environment(\.dismiss) private var dismiss
let action: () -> Void
var body: some View {
VStack {
Text("First Sheet")
Button("Dismiss") {
action()
dismiss()
}
}
}
}
Crash error:
"Application tried to present modally a view controller <TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x12a01b600> that is already being presented by <TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier_: 0x12a814e00>."
英文:
I have View with button that display sheet and after first sheet dismiss, I need to display a second sheet, when I use ObservableObject in Binding the View crash after showing the second sheet:
Root:
class Benef: ObservableObject {
@Published var val: String = ""
}
@main
struct TestApp: App {
@StateObject var beenf = Benef()
var body: some Scene {
WindowGroup {
ContentView(testt: $beenf.val)
}
}
}
ContentView:
enum Test: Identifiable {
case one
case two
var id: String {
switch self {
case .one : return "One"
case .two : return "Two"
}
}
}
struct ContentView: View {
@Environment(\.dismiss) private var dismiss
@State private var showingFirst: Test?
@State private var showingSecond: Test?
@Binding var testt: String
var body: some View {
VStack {
Button("Show First Sheet") {
showingFirst = .one
}
}
.sheet(item: $showingFirst) { tt in
FirstSheetiew {
showingSecond = .two
}
}
.sheet(item: $showingSecond) { tt in
VStack {
Text("Second Sheet")
Button("Dismiss") {
dismiss()
}
}
}
}
}
struct FirstSheetiew: View {
@Environment(\.dismiss) private var dismiss
let action: () -> Void
var body: some View {
VStack {
Text("First Sheet")
Button("Dismiss") {
action()
dismiss()
}
}
}
}
Crash error:
"Application tried to present modally a view controller <TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView: 0x12a01b600> that is already being presented by <TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier_: 0x12a814e00>."
答案1
得分: 1
这是因为 showingSecond
的值在关闭 FirstSheetView
之前已经被改变。
因此,你需要在 FirstSheetView
的 onDisappear{ }
中改变 showingSecond
的值。
以下是修复方法:
struct FirstSheetiew: View {
@Environment(\.dismiss) private var dismiss
let action: () -> Void
var body: some View {
VStack {
Text("First Sheet")
Button("Dismiss") {
//action() <-- 👀 移除
dismiss()
}
}
.onDisappear { //<-- 👀 添加
action()
}
}
}
英文:
This is because the value of showingSecond
was changed before FirstSheetView
was closed.
Therefore, you need to change the value of showingSecond
inside onDisappear{ }
of FirstSheetView
.
Here is how to fix it:
struct FirstSheetiew: View {
@Environment(\.dismiss) private var dismiss
let action: () -> Void
var body: some View {
VStack {
Text("First Sheet")
Button("Dismiss") {
//action() <-- 👀 remove
dismiss()
}
}
.onDisappear { //<-- 👀 add
action()
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论