SwiftUI:从环境对象内的函数以编程方式关闭模态 sheet

SwiftUI: Close modal sheet programmatically from a function inside an Environment Object

我有一个显示模式的主视图 sheet。因为我有多个模态,所以我使用 enum 和 State 来控制 which sheet is presented.

@State var activeSheet: Sheet?

在我的主视图中:

    Button(action: {
        activeSheet = .settings
    }, label: {
        Text(“Button”)
    })

   .sheet(item: $activeSheet) { sheet in
        switch sheet {
        case .info:
          InfoView()
        case .settings:
          SettingsView()
        }
      }

设置视图:

struct SettingsView: View {
    @Environment(\.presentationMode) private var presentationMode
    @EnvironmentObject var model: MainModel
    
    var body: some View {
        Button("Action") {
            model.myFunction()
        }
    }
}

在我的 InfoView-sheet 中,我有一个调用 EnvironmentObject 内函数的按钮。 如何在 EnvironmentObject 中完成函数后关闭 sheet?

顺便说一句,每个视图都链接到同一个 EnvironmentObject。

谢谢!

根据您要部署的最低 iOS 版本,您有两个选择:

如果您的最低 iOS 版本是 <= iOS 14,在 InfoViewSettingsView 中都使用系统环境 \.presentationMode.

struct SettingsView: View {
    @EnvironmentObject var model: MainModel
    @Environment(\.presentationMode) private var presentationMode

    var body: some View {
        Button("Dismiss") {

            /// ... Do something here prior to dismissing the sheet.
            model.MyFunction(email: email, password: password) {
                presentationMode.wrappedValue.dismiss()
            }
        }
    }
}

你的最低 iOS 版本是 iOS 15,在 InfoViewSettingsView 中都使用系统环境 \.dismiss.

struct SettingsView: View {
    @EnvironmentObject var model: MainModel
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        Button("Dismiss") {

            /// ... Do something here prior to dismissing the sheet.
            model.MyFunction(email: email, password: password) {
                dismiss()
            }
        }
    }
}

MainModel class:

class MainModel: ObservableObject {
    func myFunction(email: String, password: String, onSuccess: (() -> Void)? = nil) {         
        auth.signIn(withEmail: email, password: password) { [weak self] result, error in
            if result == nil, error != nil {
                 self?.showAlert = true
            } else {
                 guard result != nil, error == nil else { return }
                 /* Success */
                 self?.signedIn = true
                 onSuccess?()
            }
        }
    }
}

备选方案:

如果您的最低部署目标是 >= iOS 14,您可以像这样监听环境对象属性的变化:

struct SettingsView: View {
    @EnvironmentObject var model: MainModel
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        Button("Dismiss") {
            model.MyFunction(email: email, password: password)
        }
        .onChange(of: model.signedIn) { signedIn in
            if signedIn {
                dismiss()
            }
        }
    }
}