大多数显示Alert
的示例都涉及使用某种@State
作为绑定,以控制警报视图的显示/隐藏状态。
例如,showingAlert
(来源):
struct ContentView : View {
@State var showingAlert = false
var body: some View {
Button(action: {
self.showingAlert = true
}) {
Text("Show Alert")
}
.alert(isPresented: $showingAlert) {
Alert(
title: Text("Important message"),
message: Text("Wear sunscreen"),
dismissButton: .default(Text("Got it!"))
)
}
}
}
当从UI层触发警报时,这是一个很好的解决方案-就像示例中一样:
Button(action: {
self.showingAlert = true
}
但是如果我们想从控制器/视图模型层使用特定的消息触发它怎么办? 例如,我们进行网络调用- URLSession
的Publisher
可以发送Data
或Error
,我们希望将其作为Alert
中的消息推送给用户。
@State
旨在从视图的body
中进行管理,因此在这种情况下,我们应该使用@ObjectBinding
。似乎我们还需要一些message
,以便我们可以在body
中引用它:Alert(
title: Text("Important message"),
message: Text(objectBinding.message)
)
在这里,showingAlert
有点多余,因为我们可以将 message
定义为 String?
并为 presentation
创建一个绑定:
Binding<Bool>(
getValue: { objectBinding.message != nil },
setValue: { if !$0 { objectBinding.message = nil } }
)
这是一种可行的方法,它能够工作,但有两件事让我有些担忧:
message
被两个抽象管理。- 呈现/隐藏 警报状态的信息和管理泄漏到控制器 / 视图模型 / 对象绑定中。最好将 呈现/隐藏 状态私密地保留在视图中。
- 消息被保持在控制器 / 视图模型 / 对象绑定中,直到被视图 (绑定) "消耗" 掉。
有更好的方式吗?
objectBinding
。URLSession
的Publisher
(由objectBinding
管理)可以发送Data
或Error
,因此objectBinding
是错误消息的真实来源。我不确定在那里也保持Alert
的显示/隐藏状态是否是一个好习惯。 - Maciek Czarnik