如何使用 SwiftUI 呈现警报

Posted

技术标签:

【中文标题】如何使用 SwiftUI 呈现警报【英文标题】:How to present an Alert with SwiftUI 【发布时间】:2019-06-04 17:02:42 【问题描述】:

SwiftUI 中,我发现了Alert 类型。但我想知道如何使用presentation 方法来展示它。

初始化Alert 非常简单。但是怎么使用绑定呢?

struct ContentView : View 
    var body: some View 
        Button(action: 
            // Don't know how to use the `binding` below
            presentation(binding, alert: 
                Alert(title: Text("Hello"))
            )
        , label: 
            Text("asdf")
        )
    

绑定的类型是Binding<Bool>

【问题讨论】:

【参考方案1】:

.presentation() 实际上在 Beta 4 中已被弃用。这是当前与 .alert() 修饰符一起使用的版本。

struct ContentView: View 
    @State var showsAlert = false
    var body: some View 
        Button(action: 
            self.showsAlert.toggle()
        ) 
            Text("Show Alert")
        
        .alert(isPresented: self.$showsAlert) 
            Alert(title: Text("Hello"))
        
    

【讨论】:

我们如何在 Helper 中使用它?因为我们必须多次调用 Alert。 我也想知道。我很想有一个助手:“showAlert”,它需要一个标题和一个文本。例如,如果未提供参数,则显示通用警报。我试图将其作为视图结构的扩展来实现,但没有机会让它工作:/. 你可以做一个simple extension like this@Schnodderbalken【参考方案2】:

您可以使用@State 变量作为绑定。或者,您可以使用使用BindableObject@EnvironmentObject 变量。

我认为您需要在根视图上调用 presentation 才能使其工作,将其添加到 StackGroup 等似乎不起作用。

这个 sn-p 似乎可以解决问题。请注意,@State 变量在警报解除后设置为 false。

struct ContentView: View 

    @State var showsAlert = false

    var body: some View 
        Button(action: 
            self.showsAlert = true
        , label: 
            Text("asdf")
        ).presentation($showsAlert, alert: 
            Alert(title: Text("Hello"))
        )
    

【讨论】:

或者你可以使用PresentationButton,这样可以用更少的代码完成你所做的事情 不幸的是,这个答案不再正确,因为 .presentation 在 SwiftUI 中已被弃用。 如何修改它以使用处理程序处理警报!? Swift 有能力拥有处理程序。【参考方案3】:

Full Code of Alert with dismiss and okay action:

代码:

import SwiftUI

struct ContentView: View 
    @State private var isAlert = false

    var body: some View 
            Button(action: 
                self.isAlert = true
            ) 
                Text("Click Alert")
                .foregroundColor(Color.white)
            
            .padding()
            .background(Color.blue)
            .alert(isPresented: $isAlert)  () -> Alert in
                Alert(title: Text("iosDevCenters"), message: Text("This Tutorial for SwiftUI Alert."), primaryButton: .default(Text("Okay"), action: 
                    print("Okay Click")
                ), secondaryButton: .default(Text("Dismiss")))
        

    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

输出:

Output

【讨论】:

【参考方案4】:

这是呈现多个警报的解决方案。适用于iOS13-iOS15

struct YourView: View 
    enum AlertType: Identifiable 
        case first, second
        
        var id: Int 
            hashValue
        
    
    
    @State var alertType: AlertType?
    
    var body: some View 
        VStack 
            Button("Show alert #1") 
                alertType = .first
            
            
            Button("Show alert #2") 
                alertType = .second
            
        
        .alert(item: $alertType)  type in
            switch type 
            case .first:
                return Alert(title: Text("First alert"))
            case .second:
                return Alert(title: Text("Second alert"))
            
        
    

【讨论】:

【参考方案5】:

除了@tsp的回答,要显示带有两个按钮的警报并处理按钮点击动作,您可以执行以下操作:

@State var showAlert = false

var body: some View 
  Button(action: 
    self.showAlert = true
  ) 
    Text("Show Alert")
  
  .presentation($showAlert) 
      Alert(title: Text("Title"), message: Text("Message..."),
          primaryButton: .default (Text("OK")) 
            print("OK button tapped")
          ,
          secondaryButton: .cancel()
      )
  

结果:

【讨论】:

【参考方案6】:

onTapGesture 为例

struct MyRow: View 
    @State private var showingAlert = false

    var body: some View 
        HStack 
            Text("Hello")
            Text("World")
        
        .onTapGesture 
            self.showingAlert = true
        
        .alert(isPresented: $showingAlert, content: 
            Alert(title: Text("Title"), message: Text("Message"), dismissButton: .default(Text("OK")))
        )
    

【讨论】:

我无法从 swiftui 中的 draggesture 获得警报。 Anu 想法在这种情况下该怎么做?谢谢! .overlay(Rectangle() .gesture( DragGesture(minimumDistance: 50) .onEnded 如果手势正确,则手势... .alert(isPresented: $showAlert, content: Alert()...此警报无法编译 【参考方案7】:

除了@thisIsTheFoxe 的回答,你还可以实现一个简单的扩展:

扩展

public extension View 
    func alert(isPresented: Binding<Bool>,
               title: String,
               message: String? = nil,
               dismissButton: Alert.Button? = nil) -> some View 

        alert(isPresented: isPresented) 
            Alert(title: Text(title),
                  message: 
                    if let message = message  return Text(message) 
                    else  return nil  (),
                  dismissButton: dismissButton)
        
    

用法:

所以你现在可以像这样轻松使用它:

struct ContentView: View 
    @State var showsAlert = false
    var body: some View 
        Button("Show Alert") 
            self.showsAlert.toggle()
        
        .alert(isPresented: $showsAlert, title: "title", message: "Message") // <- Here
    

【讨论】:

【参考方案8】:
struct ContentView: View 

    @State var aAlert = false

    var body: some View 
        Text("Alert").tapAction 
            self.aAlert = true
        .presentation($aAlert, alert: Alert(title: Text("Alert")))
    

【讨论】:

你能详细说明你的答案吗?例如,对代码 sn-p 中有趣部分的解释或文档链接?【参考方案9】:

SwiftUI

首先创建基本警报:

Alert(title: Text("Alert title"), message: Text("Alert message"), dismissButton: .default(Text("Got it!")))

然后定义一个可绑定的条件,告知警报何时可见或不可见。切换该条件以显示/隐藏警报。

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!")))
        
    

【讨论】:

【参考方案10】:
  struct ContentView: View 
        @State private var showingAlert = false
    
        var body: some View 
            Button("Show Alert") 
                showingAlert = true
            
            .alert("Important message", isPresented: $showingAlert) 
                Button("First")  
                Button("Second")  
                Button("Third")  
            
        
    

【讨论】:

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

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

使用 SwiftUI 在条件内显示警报

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

如何在 Swiftui 上关闭应用程序时创建警报(不是通知)

SwiftUI:如何使用语义放置呈现多个 ToolbarItem?

如何使用 UIViewControllerRepresentable 在 SwiftUI 中呈现 UICollectionView