提问人:OuSS 提问时间:3/27/2023 更新时间:3/28/2023 访问量:71
SwiftUI - 在多个视图中触发错误弹出窗口
SwiftUI - Error popup fired in multiple views
问:
我尝试在我的项目中使用 MV 架构,下面是我的代码的简单示例:
struct PaymentView: View {
@StateObject private var store = PaymentStore()
var body: some View {
NavigationStack {
PaymentCreditorListView()
/* -> PaymentFormView() */
/* -> PaymentUnpaidView() */
/* -> PaymentConfirmationView() */
}
.environmentObject(store)
}
}
class PaymentStore: ObservableObject {
....
@Published var isLoading = false
@Published var popup: Popup?
private let service: PaymentService
init(service: PaymentService = PaymentService()) {
self.service = service
}
func getPaymentCreditors() async {
do {
isLoading = true
let response = try await service.fetchPaymentCreditors()
.....
isLoading = false
} catch {
isLoading = false
popup = .init(error: error)
}
}
func getPaymentForm() async {
do {
isLoading = true
let response = try await service.fetchPaymentForm()
....
isLoading = false
} catch {
isLoading = false
popup = .init(error: error)
}
}
func getPaymentUnpaid() async {
do {
isLoading = true
let response = try await service.fetchPaymentUnpaid()
.....
isLoading = false
} catch {
isLoading = false
popup = .init(error: error)
}
}
}
在每个视图上,我使用工作表来显示弹出错误,因为有时我需要为该视图做一些特定的事情(例如:调用 Web 服务或重定向等......
.sheet(item: $store.popup) { popup in
PopupView(popup: popup)
}
我现在遇到的唯一问题是,当其中一个端点返回错误时,所有使用弹出窗口的视图都会被触发,并且在控制台中收到此警告消息“尝试在已经呈现...的*上显示*”,progressLoader也有同样的问题,它将触发所有其他视图。
我错过了这种方法吗?或者有更好的方法吗?
答:
0赞
lorem ipsum
3/27/2023
#1
您可以为每个 .@State
View
首先删除
@Published var popup: Popup?
并添加到您的 sView
@State private var popup: Popup?
然后在函数中,您需要类似的东西
func getPaymentCreditors(popup: Binding<Popup?>) async {
do {
isLoading = true
let response = try await service.fetchPaymentCreditors()
.....
isLoading = false
} catch {
isLoading = false
popup.wrappedValue = .init(error: error)
}
}
工作表将引用局部变量
.sheet(item: $popup) { popup in
0赞
John Appleseed
3/28/2023
#2
这是因为您同时调用所有三个 API,并显示所有三个 API 的错误。您需要检查是否显示错误
if popup != nil {
popup = .init(error: error)
}
当然,如果你没有任何其他代码试图显示一些东西,这取决于你如何使用和其他方法。更新时,更新所有内部视图,因为您将其用作环境对象。但是,如果您不使用子视图(例如弹出窗口)中的任何更新字段,则不必担心 - 在这种情况下,子视图将更新 UI。仅当子视图依赖于更新的字段时,它才会更新 UI。getPaymentCreditors()
popup
PaymentStore
评论