Search code examples
swiftuiuihostingcontrollersafearea

UIHostingController not handling safe area correctly when presenting SwiftUI view


When hosting a SwiftUI view in UIHostingController, the view's safe area is being ignored

how can I fix that?

enter image description here

Hosting View Controller

import SwiftUI
import UIKit

class ViewController: UIViewController {
    private var hosting: UIHostingController<SwiftUIView>!

    override func viewDidLoad() {
        super.viewDidLoad()

        hosting = .init(rootView: SwiftUIView())

        view.addSubview(hosting.view)

        hosting.view.frame = view.bounds
    }
}

SwiftUI View

import SwiftUI

struct SwiftUIView: View {
    var body: some View {
        VStack {
            Text("Hello, World!")
                .font(.title)
                .foregroundColor(.white)

            Spacer(minLength: 0)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.red)
    }
}

Solution

  • It's not the right way to use a SwiftUI view in a UIKit controller. Actually, the UIHostingController is a controller and it needs to be added as a Child controller instead of just including the view itself.

    hosting = .init(rootView: SwiftUIView())
    
    self.addChild(hosting)
    view.addSubview(hosting.view)
    
    hosting.view.translatesAutoresizingMaskIntoConstraints = false
    hosting.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    hosting.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    hosting.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    hosting.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    
    hosting.didMove(toParent: self)
    

    enter image description here