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.
#Preview {
NavigationControllerStack {
ZStack {
Color.purple
.ignoresSafeArea(.all)
VStack {
Text("somethign")
}
}
}
}
I have tried
hostingController.view.insetsLayoutMarginsFromSafeArea = false
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)
}
}
This was a lot simpler than I thought it would be..
YourCustomNavigationControllerView {
ContentView()
}
.ignoresSafeArea() // <- here