SwiftUI中的全局警报
我正试图在SwiftUI中呈现一个全局警报。无论当前在屏幕上显示/呈现的是什么,此警报都应显示在所有内容的顶部(例如,工作表) 这是我的代码:SwiftUI中的全局警报,swiftui,Swiftui,我正试图在SwiftUI中呈现一个全局警报。无论当前在屏幕上显示/呈现的是什么,此警报都应显示在所有内容的顶部(例如,工作表) 这是我的代码: @main struct MyApp: App { @State private var showAlert = false var body: some Scene { WindowGroup { MainView() .onReceive(No
@main
struct MyApp: App {
@State private var showAlert = false
var body: some Scene {
WindowGroup {
MainView()
.onReceive(NotificationCenter.default.publisher(for:NSNotification.Name.SomeNotification), perform: { _ in
showAlert = true
})
.alert(
isPresented: $showAlert,
content: {Alert(title: Text("Alert!"))}
)
}
}
}
在某些情况下,这将不起作用,例如,如果在屏幕上当前显示图纸时收到通知。在这种情况下,不会显示警报,控制台上会显示以下消息:
大宗报价
[演示文稿]尝试在已演示的(来自)上演示
这是有意义的,因为我试图在已经显示图纸的视图上显示警报
在UIKit上,我使用以下类实现了这一点:
class GlobalAlertController: UIAlertController {
var globalPresentationWindow: UIWindow?
func presentGlobally(animated: Bool, completion: (() -> Void)?) {
globalPresentationWindow = UIWindow(frame: UIScreen.main.bounds)
globalPresentationWindow?.rootViewController = UIViewController()
globalPresentationWindow?.windowLevel = UIWindow.Level.alert + 1
globalPresentationWindow?.backgroundColor = .clear
globalPresentationWindow?.makeKeyAndVisible()
globalPresentationWindow?.rootViewController?.present(self, animated: animated, completion: completion)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
globalPresentationWindow?.isHidden = true
globalPresentationWindow = nil
}
}
此类允许我以以下方式在所有内容的顶部显示全局警报:
let alertController = GlobalAlertController(title: "Title", message: "Message", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Done", style: .cancel, handler: nil))
alertController.presentGlobally(animated: true, completion: nil)
有人知道如何在SwiftUI中实现类似的东西吗?刚刚发现我实际上可以使用我的旧UIKit代码来实现这一点。唯一需要更改的是添加对场景的支持(SwiftUI按设计使用场景),如下所示:
class GlobalAlertController: UIAlertController {
var globalPresentationWindow: UIWindow?
func presentGlobally(animated: Bool, completion: (() -> Void)?) {
globalPresentationWindow = UIWindow(frame: UIScreen.main.bounds)
//This is needed when using scenes.
if let currentWindowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
globalPresentationWindow?.windowScene = currentWindowScene
}
globalPresentationWindow?.rootViewController = UIViewController()
globalPresentationWindow?.windowLevel = UIWindow.Level.alert + 1
globalPresentationWindow?.backgroundColor = .clear
globalPresentationWindow?.makeKeyAndVisible()
globalPresentationWindow?.rootViewController?.present(self, animated: animated, completion: completion)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
globalPresentationWindow?.isHidden = true
globalPresentationWindow = nil
}
}
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
MainView()
.onReceive(NotificationCenter.default.publisher(for:NSNotification.Name.SomeNotification), perform: { _ in
let alertController = GlobalAlertController(title: "Title", message: "Message", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Done", style: .cancel, handler: nil))
alertController.presentGlobally(animated: true, completion: nil)
})
}
}
}
现在我可以这样显示全局警报:
class GlobalAlertController: UIAlertController {
var globalPresentationWindow: UIWindow?
func presentGlobally(animated: Bool, completion: (() -> Void)?) {
globalPresentationWindow = UIWindow(frame: UIScreen.main.bounds)
//This is needed when using scenes.
if let currentWindowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
globalPresentationWindow?.windowScene = currentWindowScene
}
globalPresentationWindow?.rootViewController = UIViewController()
globalPresentationWindow?.windowLevel = UIWindow.Level.alert + 1
globalPresentationWindow?.backgroundColor = .clear
globalPresentationWindow?.makeKeyAndVisible()
globalPresentationWindow?.rootViewController?.present(self, animated: animated, completion: completion)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
globalPresentationWindow?.isHidden = true
globalPresentationWindow = nil
}
}
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
MainView()
.onReceive(NotificationCenter.default.publisher(for:NSNotification.Name.SomeNotification), perform: { _ in
let alertController = GlobalAlertController(title: "Title", message: "Message", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Done", style: .cancel, handler: nil))
alertController.presentGlobally(animated: true, completion: nil)
})
}
}
}
这是可行的,尽管更快捷的方法会更好。以下内容解决了类似的问题,因此应该会有所帮助。