iosswiftswiftuiuinavigationcontrolleruiviewcontrollerrepresentable

How to change the background color of the status bar in SwiftUI when creating a custom NavigationController View


I wanted to experiment a little using UINavigationController with SwiftUI App Lifecycle

I created a Custom Navigation Controller named JDNavigationController. It does not do much other than having the @Observable macro

public struct NavigationControllerStack<Content: View>: UIViewControllerRepresentable {
    private let initialView: () -> Content

    @State private var controller = JDNavigationController()

    public init(content: @escaping () -> Content) {
        self.initialView = content
    }

    public func makeUIViewController(context: Context) -> JDNavigationController {
        let viewController = self.initialView()
            .environment(self.controller)
            .viewController

        self.controller.viewControllers = [
            viewController
        ]

        return controller
    }
    
    public func updateUIViewController(_ uiViewController: JDNavigationController, context: Context) {

    }

    public typealias UIViewControllerType = JDNavigationController
}

when I check, the functionality of the navigation controller works as expected, however, I can't for the life of me to change the background color of the status bar.

enter image description here

#Preview {
    NavigationControllerStack {
        ZStack {
            Color.purple
                .ignoresSafeArea(.all)

            VStack {
                Text("somethign")
            }
        }
    }
}

I have tried

none seems to work.

I opened the View Debugger it looks like the white portion comes from the UIHosting Controller but I am not sure what I can do to fix it.

Edit: Additional information regarding the setup.

I wrote an extension to SwiftUI's view to convert it to a UIViewController

extension View {
    public var viewController: UIViewController {
        UIHostingController(rootView: self)
    }
}

the following is the implementation of JDNavigationController

@Observable
public final class JDNavigationController: UINavigationController {
    public func pushView<V: View>(
        _ view: @autoclosure () -> V,
        animated: Bool = true
    ) {
        self.pushViewController(
            view()
                .environment(self)
                .viewController,
            animated: animated
        )
    }

    public func presentView<V: View>(
        _ view: @autoclosure () -> V,
        animated: Bool = true,
        completion: (() -> Void)? = nil
    ) {
        self.present(
            view()
                .environment(self)
                .viewController,
            animated: animated,
            completion: completion
        )
    }

    public func alert(
        title: String? = nil,
        messsage: String? = nil,
        actions: [UIAlertAction] = [],
        animated: Bool = true,
        completion: (() -> Void)? = nil,
        preferredStyle: UIAlertController.Style = .alert
    ) {
        let alertController = UIAlertController(title: title, message: messsage, preferredStyle: preferredStyle)

        actions.forEach {
            alertController.addAction($0)
        }

        self.present(alertController, animated: animated, completion: completion)
    }
}


Solution

  • This was a lot simpler than I thought it would be..

    YourCustomNavigationControllerView {
        ContentView()
    }
    .ignoresSafeArea() // <- here