如何使用 SwiftUI 连续呈现两个警报视图

Posted

技术标签:

【中文标题】如何使用 SwiftUI 连续呈现两个警报视图【英文标题】:How to consecutively present two alert views using SwiftUI 【发布时间】:2019-11-13 09:54:21 【问题描述】:

我想在单击第一个警报视图的关闭按钮后立即显示第二个警报视图。

Button(action: 
     self.alertIsVisible = true
) 
     Text("Hit Me!")

.alert(isPresented: $alertIsVisible)  () -> Alert in
    return Alert(title: Text("\(title)"), message: Text("\n"), dismissButton:.default(Text("Next Round"), action: 
        if self.score == 100 
            self.bonusAlertIsVisible = true
    
    .alert(isPresented: $bonusAlertIsVisible) 
        Alert(title: Text("Bonus"), message: Text("You've earned 100 points bonus!!"), dismissButton: .default(Text("Close")))
)
)

但是,它给了我一个错误'Alert.Button' is not convertible to 'Alert.Button?' 如果我将此段置于dismissButton 的范围之外,它将覆盖之前的.alert。 那么我该怎么做呢,我只想在单击第一个警报的关闭按钮后弹出第二个警报。 谢谢。

【问题讨论】:

这能回答你的问题吗? How can I have two alerts on one view in SwiftUI? 不,不一样,我也试过那个,但是你需要点击两次“Hit me”按钮才能弹出第二个警报视图,我想点击第一个警报的关闭按钮 【参考方案1】:

它出现了(用 Xcode 11.2 测试):

    虽然没有记录,但不允许添加多个 一个视图构建器序列中的 .alert 修饰符 - 仅适用于最新版本 不允许在 EmptyView 中添加 .alert 修饰符,它不起作用 完全没有

我找到了@Rohit 提出的替代解决方案。在某些情况下,很多警报,这可能会导致代码更简单。

struct TestTwoAlerts: View 
    @State var alertIsVisible = false
    @State var bonusAlertIsVisible = false

    var score = 100
    var title = "First alert"

    var body: some View 
        VStack 
            Button(action: 
                 self.alertIsVisible = true
            ) 
                 Text("Hit Me!")
            
            .alert(isPresented: $alertIsVisible) 
                Alert(title: Text("\(title)"), message: Text("\n"), dismissButton:.default(Text("Next Round"), action: 
                    if self.score == 100 
                        DispatchQueue.main.async  // !! This part important !!
                            self.bonusAlertIsVisible = true
                        
                    
                ))
            
            Text("")
            .alert(isPresented: $bonusAlertIsVisible) 
                    Alert(title: Text("Bonus"), message: Text("You've earned 100 points bonus!!"), dismissButton: .default(Text("Close")))
            
        
    


struct TestTwoAlerts_Previews: PreviewProvider 
    static var previews: some View 
        TestTwoAlerts()
    

【讨论】:

干杯人!你能告诉我当我们添加这部分代码时会发生什么:DispatchQueue.main.async self.bonusAlertIsVisible = true ? 这个状态会在主循环的下一个事件中改变,所以不会和第一个alert冲突,仍然是打开的。如果同步改变这个状态是不行的,因为这里不能有两个打开的alert。【参考方案2】:

请尝试以下代码。

使用SwiftUI连续呈现两个警报视图

struct ContentView: View 

    @State var showAlert: Bool = false
    @State var alertIsVisible: Bool = false
    @State var bonusAlertIsVisible: Bool = false

    var body: some View 

        NavigationView 

            Button(action: 
                self.displayAlert()
            ) 
                Text("Hit Me!")
            
            .alert(isPresented: $showAlert)  () -> Alert in
                if alertIsVisible 
                    return Alert(title: Text("First alert"), message: Text("\n"), dismissButton:.default(Text("Next Round"), action: 
                        DispatchQueue.main.async 
                            self.displayAlert()
                        
                     )
                   )
                
                else 
                    return Alert(title: Text("Bonus"), message: Text("You've earned 100 points bonus!!"), dismissButton:.default(Text("Close"), action: 
                                self.showAlert = false
                                self.bonusAlertIsVisible = false
                                self.alertIsVisible = false
                        )
                    )
                
            
            .navigationBarTitle(Text("Alert"))
        
    

    func displayAlert() 

       self.showAlert = true
       if self.alertIsVisible == false 
            self.alertIsVisible = true
            self.bonusAlertIsVisible = false
       
       else 
            self.alertIsVisible = false
            self.bonusAlertIsVisible = true
       
    

【讨论】:

天才!所以就像我们在主调度队列中异步添加 $showAlert=false 一样,它会显示 .alert 两次而不需要单击按钮?

以上是关于如何使用 SwiftUI 连续呈现两个警报视图的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SwiftUI 呈现警报

在视图外触发时如何绑定 SwiftUI.Alert 的呈现?

如何在 SwiftUI 中动态推送视图或呈现视图?

一个视图中的多个警报只能在 swiftui 中始终使用最后一个警报

SwiftUI 呈现警报。 “警报”初始化程序的结果未使用

如何将不在根层次结构中的 SwiftUI 视图呈现为 UIImage?