import SwiftUI import UIKit struct TextInputView: View { @State private var textFieldText = "" var body: some View { TextField("Type here", text: $textFieldText) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() } } struct KeyboardAnchoredContainer: UIViewControllerRepresentable { typealias ViewController = KeyboardAnchoredContainerViewController @ViewBuilder var content: () -> Content func makeUIViewController(context: Context) -> ViewController { ViewController(content: content()) } func updateUIViewController(_ uiViewController: ViewController, context: Context) {} } class KeyboardAnchoredContainerViewController: UIViewController { var content: Content init(content: Content) { self.content = content super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { setUpContent() setUpInput() } private func setUpContent() { let hostingView = UIHostingController(rootView: content) hostingView.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(hostingView.view) // Anchor content to top of keyboard layout NSLayoutConstraint.activate([ hostingView.view.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor), hostingView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), hostingView.view.topAnchor.constraint(equalTo: view.topAnchor), ]) } private func setUpInput() { let textInputView = TextInputView() let hostingView = UIHostingController(rootView: textInputView) view.addSubview(hostingView.view) hostingView.view.translatesAutoresizingMaskIntoConstraints = false // Anchor input to top of keyboard layout NSLayoutConstraint.activate([ hostingView.view.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor), hostingView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), hostingView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), hostingView.view.heightAnchor.constraint(equalToConstant: 46) ]) } } struct ContentView: View { var body: some View { KeyboardAnchoredContainer { VStack { ScrollView { ForEach(0..<20) { index in HStack { Text("Item \(index + 1)") .padding() Spacer() } } } .scrollDismissesKeyboard(.interactively) .scrollClipDisabled() .defaultScrollAnchor(.bottom) // Inset content slightly to avoid overlap with text input. .contentMargins([.bottom], EdgeInsets(top: 0, leading: 0, bottom: 40, trailing: 0)) } } // This is key, otherwise the text input taps into SwiftUI's keyboard safe area avoidance. .ignoresSafeArea() } } #Preview { ContentView() }