iosswiftswiftuiuikituinavigationcontroller

How to apply Content ViewController background to bottom SafeArea in UINavigationController?


While porting my existing UIKit based app to SwiftUI I struggle with a simple task:

A UIViewControllerRepresentable holds a UINavigationController.

The UINavigationController displays VCs with different background colors. These are not applied to the bottom safe area. How can I change this, so that the safe area has the color of the active child VC?

enter image description here

struct SomeSheetContent: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        let firstVC = UIViewController()
        firstVC.view.backgroundColor = .green
        firstVC.title = "First VC"
        firstVC.edgesForExtendedLayout = [.all]
        firstVC.extendedLayoutIncludesOpaqueBars = true

        let button = UIButton(type: .system)
        button.setTitle("Next", for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 20, weight: .bold)
        button.addTarget(context.coordinator, action: #selector(Coordinator.didTapButton), for: .touchUpInside)

        firstVC.view.addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: firstVC.view.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: firstVC.view.centerYAnchor)
        ])
        

        let navVC = UINavigationController(rootViewController: firstVC)
        navVC.navigationBar.isTranslucent = false
        navVC.edgesForExtendedLayout = [.all]
        
        context.coordinator.navigationController = navVC
        
        return navVC
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) { }

    class Coordinator: NSObject {
        let parent: SomeSheetContent
        weak var navigationController: UINavigationController?

        init(_ parent: SomeSheetContent) {
            self.parent = parent
        }

        @objc func didTapButton() {
            let secondVC = UIViewController()
            secondVC.view.backgroundColor = .orange
            secondVC.title = "Second VC"
            secondVC.edgesForExtendedLayout = [.all]
            secondVC.extendedLayoutIncludesOpaqueBars = true

            navigationController?.pushViewController(secondVC, animated: true)
        }
    }
}

Solution

  • You should have the SomeSheetContent ignore safe areas at the use site. For example:

    .sheet(isPresented: $isPresented)
        SomeSheetContent()
            .ignoresSafeArea()
    }