如何在SwiftUI中显示一个UIAlertController?

15
在UIKit中,通常会使用UIAlertController来呈现模态弹出警告消息以响应某些操作。
在SwiftUI中是否有模态警报控制器类型?
是否有一种方法可以从SwiftUI类中呈现UIAlertController?似乎可以使用UIViewControllerRepresentable实现,但不确定是否需要这样做。
4个回答

13

这个很简单:

class func alertMessage(title: String, message: String) {
    let alertVC = UIAlertController(title: title, message: message, preferredStyle: .alert)
    let okAction = UIAlertAction(title: "OK", style: .default) { (action: UIAlertAction) in
    }
    alertVC.addAction(okAction)
    
    let viewController = UIApplication.shared.windows.first!.rootViewController!
    viewController.present(alertVC, animated: true, completion: nil)
}

将其放入Helper类中。
用法:
Helper.alertMessage(title: "Test-Title", message: "It works - even in SwiftUI")

1
我从按钮的操作中调用了Helper.alertMessage(...),谢谢,它按预期工作。 - LetsGoBrandon
1
移除类声明和操作上的闭包,仍然可以工作。我使用last而不是first,这对我起作用了。 - Israel Manzo
5
从 iOS 15 开始,rootViewController已过时。如果您正在使用SwiftUI,则最好更新到其.alert(isPresented:, content:)方法。 - Andres Canella
如果屏幕上有一个表格正在显示,这将无法工作。 - Stephen.W
请不要这样做。这是一个巨大的黑客行为,非常脆弱。请使用被接受的答案。 - Joe Hankin

7

请使用Alert代替。

import SwiftUI

struct SwiftUIView: View {
    @State private var showAlert = false;

    var body: some View {
        Button(action: { self.showAlert = true }) {
            Text("Show alert")
        }.alert(
            isPresented: $showAlert,
            content: { Alert(title: Text("Hello world")) }
        )
    }
}

绑定 isPresented以控制演示。


谢谢。在SwiftUI中使用Alert(https://developer.apple.com/documentation/swiftui/alert)似乎是合适的选择。绑定演示是否符合预期范例? - myuiviews
一般来说可以,多亏了"单一真理源"的东西。 例如,您可以使用MVVM并从ViewModel触发showAlert标志。 - EvZ

0
我正在使用UIViewController的扩展来获取当前视图控制器,并使用UIAlertController来呈现“警报”。也许你可以尝试以下内容:
UIViewController的扩展
extension UIViewController {
class func getCurrentVC() -> UIViewController? {
var result: UIViewController?
var window = UIApplication.shared.windows.first { $0.isKeyWindow }
        if window?.windowLevel != UIWindow.Level.normal {
            let windows = UIApplication.shared.windows
            for tmpWin in windows {
                if tmpWin.windowLevel == UIWindow.Level.normal {
                    window = tmpWin
                    break
                }
            }
        }
        let fromView = window?.subviews[0]
        if let nextRespnder = fromView?.next {
            if nextRespnder.isKind(of: UIViewController.self) {
                result = nextRespnder as? UIViewController
                result?.navigationController?.pushViewController(result!, animated: false)
            } else {
                result = window?.rootViewController
            }
        }
        return result
    }
}

UIAlertController 的扩展

extension UIAlertController {
    //Setting our Alert ViewController, presenting it.
    func presentAlert() {
        ViewController.getCurrentVC()?.present(self, animated: true, completion: nil)
    }

    func dismissAlert() {
        ViewController.getCurrentVC()?.dismiss(animated: true, completion: nil)
    }
}

现在你可以创建自己的showAlert函数了

func showMyAlert() {
let myAlert = UIAlertController(title: "Confirm order", message: "Are you sure to order two box of chocolate?", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok!", style: .default) { (_) in
print("You just confirm your order")
} 
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in
print(You cancel it already!)
}
myAlert.addAction(okAction)
myAlert.addAction(cancelAction)
myAlert.presentAlert()
}

希望我的回答能对你有所帮助。 :-)

它在我的项目上运行良好。但我不知道它是否在你的项目上也能正常工作。 - Spencer Reid

-2

你可以使用notificationCenter在SwiftUI中展示UIKit Alert

在SceneDelegate.swift文件的"func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)"方法中插入以下代码 {

   NotificationCenter.default.addObserver(self, selector: #selector(self.showAlert), name: Notification.Name("showAlert"), object: nil)

并添加此函数

  @objc private func showAlert(notification: NSNotification){
        let msg: String = notification.object as! String
        let alert =  UIAlertController(title: "Title", message: msg, preferredStyle: .alert)
        let cancelAction = UIAlertAction(title: "οκ", style: .cancel) { (action) in
        }
        alert.addAction(cancelAction)
        DispatchQueue.main.async {
            self.window?.rootViewController?.present(alert, animated: true, completion: nil)
        }
    }

现在,您可以通过在SwiftUI类中的操作中编写此代码,使应用程序显示一个带有UIKit AlertController的消息。
 var body: some View {
        Button(action:{
               NotificationCenter.default.post(name: Notification.Name("showAlert"), object: "Ελέγξτε το δίκτυο σας και προσπαθήστε αργότερα.")
 }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接