在swiftUI中调用警报的方法应该比以往任何时候都简单,这是一个简单的示例
struct ContentView: View {
@State private 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!")))
}
}
}
但是,即使我正在调用警报并可以验证该方法正在被调用,我的警报也不会显示。
在我的代码中,我有以下结构体
private struct resetButton: View {
@State var isResetting = false
var body: some View {
Button("Reset"){
self.isResetting = true
}.alert(isPresented: $isResetting) {
print("We get here")
return
Alert(title: Text("Are you sure?"), message: Text("This will erase your Access Key."), primaryButton: .destructive(Text("Reset")) {
clearToken()
clearAccessKey()
clearUsername()
}, secondaryButton: .cancel(Text("Cancel")))
}
}
}
在主视图中仅由resetButton()
调用。
但是,当我按下此按钮时,尽管isResetting
等于true,也不会显示警报。我已验证控制台打印时正在调用我的.alert
方法
我们到了
第一次按下按钮。
但是,警报永远不会显示。
在同一视图中的其他位置正确显示警报,
.alert(isPresented: $failedLogin) {
self.password = ""
return
Alert(title: Text("Invalid Login"), message: Text("Please verify your credentials and try again"), dismissButton: .default(Text("Ok")))
}
但是,将名为@State
的{{1}}变量设置为true时,将永远不会显示上述警报。
我的第一印象是,这可能是Swift中的错误,如果是的话,我会向苹果报告。但是,也许由于我的错误,我正在做的事情无法正常工作。
编辑:
正如下面的答案所阐明的,问题似乎与我的failedLogin
试图在已经包含警报的视图中引发警报这一事实有关。显然,在一个视图中不能有多个警报。
答案 0 :(得分:10)
您可以使用.alert( item:)代替.alert( isPresented:):
动态显示警报struct AlertItem: Identifiable {
var id = UUID()
var title: Text
var message: Text?
var dismissButton: Alert.Button?
}
struct ContentView: View {
@State private var alertItem: AlertItem?
var body: some View {
VStack {
Button("First Alert") {
self.alertItem = AlertItem(title: Text("First Alert"), message: Text("Message"))
}
Button("Second Alert") {
self.alertItem = AlertItem(title: Text("Second Alert"), message: nil, dismissButton: .cancel(Text("Some Cancel")))
}
Button("Third Alert") {
self.alertItem = AlertItem(title: Text("Third Alert"))
}
}
.alert(item: $alertItem) { alertItem in
Alert(title: alertItem.title, message: alertItem.message, dismissButton: alertItem.dismissButton)
}
}
}
答案 1 :(得分:0)
所以我仍然不是100%知道为什么它不能以这种方式发布警报?但是我只需将警报放在主视图中就可以解决此问题。
我将checkAllOf()
变量checkAllOf
更改为绑定bool,并在主类中调整了新的状态变量。然后,我只复制了function toggle(i, j) {
b = document.getElementById("but_" + i + j)
if (!b) return;
t = b.innerHTML
if (t == "X") {
b.innerHTML = "O";
b.setAttribute("style", "color:red; background-color:yellow")
}
if (t == "O") {
b.innerHTML = "X";
b.setAttribute("style", "color:white; background-color:black")
}
}
// Check if board is solved
function checkAllOff() {
for (var i = 0; i < 5; i++)
for (var j = 0; j < 5; j++) {
t = document.getElementById("but_" + i + j).innerHTML
if (t == "O")
return false
}
return (true);
}
function press(i, j) {
toggle(i, j)
toggle(i, j - 1)
toggle(i, j + 1)
toggle(i + 1, j)
toggle(i - 1, j)
if (checkAllOff()) {
console.log("All lights are out!You win!")
}
}
function generateGrid() {
var d = document.getElementById("button-grid");
var table = document.createElement("table");
d.appendChild(table);
for (var i = 0; i < 5; i++) {
var row = document.createElement("tr");
for (var j = 0; j < 5; j++) {
var cell = document.createElement("td");
cell.innerHTML = "<button type=button id=but_" + i + j +
" onclick=\"press(" + i + ',' + j + ")\"" +
" style=\"color:red; background-color:yellow\"" +
">O</button>";
row.appendChild(cell);
}
table.appendChild(row);
}
}
window.onload = function() {
generateGrid();
};
,这似乎可以解决问题。
结构现在看起来像这样
<div align="center" id="button-grid">
<h1> *** Lights Off *** </h1>
<h2> Click on buttons until they all turn black </h2>
</div>
和警报相同,但现在在调用@State
的类中。
编辑:
因此,SwiftUI似乎不允许您从同一视图调用多个警报,但是,如果您希望在同一视图中调用多个警报,则有一种解决方法。
您可以从视图内部的任何位置调用警报,以便使用以下解决方案。
isResetting
这里要注意的是,如果将这些警报中的任何一个放置在Vstack上,一个警报都将不起作用。如果将它们放在单独的视图上,则可以按预期的方式调用它们。
也许这将在以后的更新中得到纠正?同时,这是解决此问题的解决方案。
答案 2 :(得分:0)
就我而言,我通过在警报前添加一个空文本来解决它。
private struct exampleAlert: View {
@State var alert1 = false
@State var alert2 = false
var body: some View {
Vstack{
Button("alert 1"){
self.alert1 = true
}
Button("alert 2"){
self.alert2 = true
}
}
Vstack{
Text("")
.alert(isPresented: $alert1) {
Alert(title: Text("Important message"), message: Text("This alert can show"), dismissButton: .default(Text("Got it!")))
}
Text("")
.alert(isPresented: $alert2) {
Alert(title: Text("Important message"), message: Text("This alert can also show"), dismissButton: .default(Text("Got it!")))
}
}
}
}