我想将两个唯一的警报附加到同一Button
视图。当我使用下面的代码时,只有底部的警报起作用。
我正在macOS Catalina上使用Xcode 11的正式版本。
@State private var showFirstAlert = false
@State private var showSecondAlert = false
Button(action: {
if Bool.random() {
showFirstAlert = true
} else {
showSecondAlert = true
}
}) {
Text("Show random alert")
}
.alert(isPresented: $showFirstAlert) {
// This alert never shows
Alert(title: Text("First Alert"), message: Text("This is the first alert"))
}
.alert(isPresented: $showSecondAlert) {
// This alert does show
Alert(title: Text("Second Alert"), message: Text("This is the second alert"))
}
Run Code Online (Sandbox Code Playgroud)
我希望在设置showFirstAlert
为true 时显示第一个警报,而在我设置为true时希望显示第二个警报showSecondAlert
。只有第二个警报显示其状态为true时,但第一个警报什么也不做。
Ben*_*Ben 22
这个解决方案有一个变体,它只使用一个状态变量而不是两个。它使用了这样一个事实,即有另一种.alert()
形式接受一个Identifiable
项目而不是一个 Bool,因此可以传递额外的信息:
struct AlertIdentifier: Identifiable {
enum Choice {
case first, second
}
var id: Choice
}
struct ContentView: View {
@State private var alertIdentifier: AlertIdentifier?
var body: some View {
HStack {
Button("Show First Alert") {
self.alertIdentifier = AlertIdentifier(id: .first)
}
Button("Show Second Alert") {
self.alertIdentifier = AlertIdentifier(id: .second)
}
}
.alert(item: $alertIdentifier) { alert in
switch alert.id {
case .first:
return Alert(title: Text("First Alert"),
message: Text("This is the first alert"))
case .second:
return Alert(title: Text("Second Alert"),
message: Text("This is the second alert"))
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
如果您有更复杂的逻辑(例如,来自一个按钮的多个警报),这是另一种灵活的方法。您基本上可以附加.alert
到任何View
按钮并将警报逻辑与按钮分开,如下所示:
EmptyView() 对我不起作用。在 Xcode 12.4 中测试
// loading alert
Text("")
.alert(isPresented: $showLoadingAlert, content: {
Alert(title: Text("Logging in"))
})
.hidden()
// error alert
Text("")
.alert(isPresented: $showErrorAlert, content: {
Alert(title: Text("Wrong passcode"), message: Text("Enter again"), dismissButton: .default(Text("Confirm")))
})
.hidden()
Run Code Online (Sandbox Code Playgroud)
的第二个调用将.alert(isPresented)
覆盖第一个。您真正想要的是Binding<Bool>
指示是否显示警报,以及应该从其后的闭包中返回警报的某些设置.alert(isPresented)
。您可以为此使用Bool,但是我继续使用枚举来完成此操作,因为它扩展为两个以上的警报。
enum ActiveAlert {
case first, second
}
struct ToggleView: View {
@State private var showAlert = false
@State private var activeAlert: ActiveAlert = .first
var body: some View {
Button(action: {
if Bool.random() {
self.activeAlert = .first
} else {
self.activeAlert = .second
}
self.showAlert = true
}) {
Text("Show random alert")
}
.alert(isPresented: $showAlert) {
switch activeAlert {
case .first:
return Alert(title: Text("First Alert"), message: Text("This is the first alert"))
case .second:
return Alert(title: Text("Second Alert"), message: Text("This is the second alert"))
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我改进了一点 Ben 的回答。您可以使用 .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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,在 iOS 16 中,一个视图上有两个警报不再是问题。
alert(isPresented:content:)
并alert(item:content:)
在该线程的许多答案中提到的以及该Alert
结构均已弃用。
建议仅使用alert(_:isPresented:actions:message:)
替代方案或其变体之一。例如:
struct ContentView: View {
@State private var isFirstAlertPresented = false
@State private var isSecondAlertPresented = false
var body: some View {
VStack {
Button("Show first alert") {
isFirstAlertPresented = true
}
Button("Show second alert") {
isSecondAlertPresented = true
}
}
.alert(
"First alert",
isPresented: $isFirstAlertPresented,
actions: {
Button("First OK") {}
},
message: {
Text("First message")
}
)
.alert(
"Second alert",
isPresented: $isSecondAlertPresented,
actions: {
Button("Second OK") {}
},
message: {
Text("Second message")
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
251 次 |
最近记录: |