UIHostingView failed to present view, which already presenting

183 Views Asked by At

I create the custom alert, but when I try to show it on .sheet View, I have this error -

2023-08-05 00:21:15.880778+0200 MyApp[759:72430] [Presentation] Attempt to present <_TtGC7SwiftUI19UIHostingControllerV6Events11CustomAlert_: 0x108009600> on <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x103022800> (from <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x103022800>) which is already presenting <_TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView_: 0x10680a000>.

this is my code -


extension View {
    func customAlert(args) -> some View {
        if let topController = UIApplication.shared.windows.first?.rootViewController {
           let alert = CustomAlert(args)
           let hostingController = UIHostingController(rootView: alert)
           hostingController.modalPresentationStyle = .overFullScreen
           hostingController.modalTransitionStyle = .crossDissolve
           hostingController.view.backgroundColor = .clear

           topController.present(hostingController, animated: false)
        }

        return self
     }
}

how can I fix it?

please help me! I don't now, why is it happing:(

1

There are 1 best solutions below

1
Palwandew On BEST ANSWER

.sheet modifier presents a view controller modally on the current window's root view controller. When we need to present a view controller on top of already presented view controller we can use presentedViewController property of UIViewController to check if the root view controller has already presented any VC.

extension View {
    func customAlert(args) -> some View {
        if let topController = UIApplication.shared.windows.first?.rootViewController {
            let alert = CustomAlert(args)
            let hostingController = UIHostingController(rootView: alert)
            hostingController.modalPresentationStyle = .overFullScreen
            hostingController.modalTransitionStyle = .crossDissolve
            hostingController.view.backgroundColor = .clear
            
            // check if a VC is already presented modally
            if let presentedVC = topController.presentedViewController {
                presentedVC.present(hostingController, animated: false)
            } else {
                topController.present(hostingController, animated: false)
            }
        }
        
        return self
    }
}