import UIKit import SwiftUI class KeyboardViewController: UIInputViewController { override func viewDidLoad() { super.viewDidLoad() struct ContentView: View { @State var enlarge = false var body: some View { Color.red .frame(height: enlarge ? 400 : 200) .onTapGesture { enlarge.toggle() } } } // Key fix #1: // Override UIHostingController.viewWillLayoutSubviews's method class HostingController: UIHostingController { override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() if #available(iOS 15.0, *) { // Workaround for an iOS 15 SwiftUI bug(?): // The intrinsicContentSize of UIView is not updated // when the internal SwiftUI view changes size. view.invalidateIntrinsicContentSize() } } } let hostingController = HostingController(rootView: ContentView()) let hostingView = hostingController.view! // Key fix #2: // Add the hosting controller as a child view controller addChild(hostingController) view.addSubview(hostingView) hostingController.view.translatesAutoresizingMaskIntoConstraints = false // Key fix #3: // Constraining the top & bottom of the hosting view to its parent NSLayoutConstraint.activate([ hostingView.topAnchor.constraint(equalTo: view.topAnchor), hostingView.bottomAnchor.constraint(equalTo: view.bottomAnchor), hostingView.leftAnchor.constraint(equalTo: view.leftAnchor), hostingView.rightAnchor.constraint(equalTo: view.rightAnchor) ]) // Key fix #4: // Let the hosting controller know it has finished // moving to the parent view controller. hostingController.didMove(toParent: self) } }