0

This question is quite similar to this question however, the solution there does not work for me.

I have a predominantly UIKit app and now we are building some views using SwiftUI.

To show alert pop ups, we are using this SwiftMessages library

For simplicity, imagine there is a singleton which has this function which we already use to show alerts on several UIKit views:

class Router {
    static func showAlert(on viewController: UIViewController) {
        SwiftMessagesLibrary.showAlert(on: viewController)
    }
}

I want invoke that same function of showing an alert but from my SwiftUI View.

At the moment I do not see anything. My navigation hierarchy is as follows:

  • Swift UI View 1 with a NavigationView presents Swift UI View 2 modally
  • Swift UI View 2 with a NavigationView presents Swift UI View 3 modally
  • Swift UI View 3 also has a NavigatioView which needs to show the alert which can be presented over a UIViewController

Based on the question above, I tried:

struct EmptyViewController: UIViewControllerRepresentable {

    let navController =  UINavigationController()


    func makeUIViewController(context: Context) -> UINavigationController {
        navController.setNavigationBarHidden(true, animated: false)
        let viewController = UIViewController()
        navController.addChild(viewController)
        return navController
    }

    func updateUIViewController(_ pageViewController: UINavigationController, context: Context) {
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }

    class Coordinator: NSObject {
        var parent: LoginViewController

        init(_ loginViewController: LoginViewController) {
            self.parent = loginViewController
        }
    }

    func showError() {
        Router.showAlert(on: navController)
    }

}

Then this is how I use it in my SwiftUI View

struct LandingView: View {
    let emptyView = EmptyViewController()

    var body: some View {

        ZStack {
                    emptyView
                     
                    Button(action: { emptyView.showError() } ) {
                        Text("Tap")
                    }
        }
    }
}

I still don't get anything to show.

The closest I have got to seeing something is when I try to access the root view controller through the window:

if let windowScene = UIApplication.shared.windows.first?.windowScene,
   let rootViewController = windowScene.windows.first?.rootViewController {
    Router.showAlert(on: rootViewController)
}

I don't like this approach as it doesn't seem too clean and still doesn't give the desirable effect as it shows below both my modal views.

Any ideas on how I can achieve the desired ?

Shawn Frank
  • 4,381
  • 2
  • 19
  • 29

0 Answers0