我正在构建 Swift 应用程序,并试图找出如何显示警报。我有一个单独的 swift 文件正在执行一些计算,并且在某些条件下我希望它向用户显示警报,基本上告诉他们出了问题。但是,我看到的大多数示例都要求警报位于
ContentView
内或以其他方式连接到视图,并且我无法弄清楚如何从任何视图之外的单独文件显示警报。
我见过的大多数例子都是这样的:
struct ContentView: View {
@State private var showingAlert = false
var body: some View {
Button("Show Alert") {
showingAlert = true
}
.alert("Important message", isPresented: $showingAlert) {
Button("OK", role: .cancel) { }
}
}}
如果我正确理解你的问题,当计算中发生某些情况时,你希望在用户界面上显示
alert
。
计算发生在代码中的其他位置,例如监视传感器的任务。
这里我提出一种方法,使用
NotificationCenter
,如示例代码所示。无论何时何地,只要您在代码中,发送 NotificationCenter.default.post...
(如示例代码所示),警报就会弹出。
class SomeClass {
static let showAlertMsg = Notification.Name("ALERT_MSG")
init() {
doCalculations() // simulate showing the alert in 2 secs
}
func doCalculations() {
//.... do calculations
// then send a message to show the alert in the Views "listening" for it
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
NotificationCenter.default.post(name: SomeClass.showAlertMsg, object: nil)
}
}
}
struct ContentView: View {
let calc = SomeClass() // for testing, does not have to be in this View
@State private var showingAlert = false
var body: some View {
Text("calculating...")
.alert("Important message", isPresented: $showingAlert) {
Button("OK", role: .cancel) { }
}
// when receiving the msg from "outside"
.onReceive(NotificationCenter.default.publisher(for: SomeClass.showAlertMsg)) { msg in
self.showingAlert = true // simply change the state of the View
}
}
}
还有另一种解决方案。我们可以只发送一个参数作为@ObservedObject。
public class Parameter: ObservableObject {
@Published public var cardNo: String
public init(cardNo: String) {
self.cardNo = cardNo
}
}
struct CardView: View {
@ObservedObject var parameter: Parameter
var body: some View {
Text("The card No: " + parameter.cardNo)
.onReceive(parameter.$cardNo) { _ in
// do what you want
}
}
}
// so here create init the cardView,
var parameter: Parameter = .init(cardNo: "x1234")
CardView(parameter: parameter)
// and also we can change the cardNo outside from other thread
parameter.cardNo = "x3456"