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,在 InfoView
和 SettingsView
中都使用系统环境 \.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,在 InfoView
和 SettingsView
中都使用系统环境 \.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()
}
}
}
}
我有一个显示模式的主视图 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,在 InfoView
和 SettingsView
中都使用系统环境 \.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,在 InfoView
和 SettingsView
中都使用系统环境 \.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()
}
}
}
}