SwiftUI 中的全局警报
Posted
技术标签:
【中文标题】SwiftUI 中的全局警报【英文标题】:Global alert in SwiftUI 【发布时间】:2020-10-25 10:21:26 【问题描述】:我正在尝试在 SwiftUI 中显示全局警报。无论当前在屏幕上显示/呈现什么(例如工作表),此警报都应显示在所有内容之上。
这是我的代码:
@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!"))
)
这在某些情况下不起作用,例如,如果在屏幕上当前显示工作表时收到通知。在这种情况下,不会显示警报,控制台上会显示以下消息:
块引用 [演示]尝试本
上 TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier EM> _:0x7fbee642ac60>(来自 TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier EM> _:0x7fbee642ac60>),其已经呈现TtGC7SwiftUI22SheetHostingControllerVS_7AnyView: 0x7fbee8405360>.
这是有道理的,因为我试图在已经呈现工作表的视图上呈现警报。
在 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 中实现类似的东西吗?
【问题讨论】:
下面解决了类似的问题***.com/a/63259094/12299030,应该会有所帮助。 【参考方案1】:刚刚发现我实际上可以使用我的旧 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)
)
它可以工作,虽然更类似于 SwiftUI 的方法会很好。
【讨论】:
以上是关于SwiftUI 中的全局警报的主要内容,如果未能解决你的问题,请参考以下文章