Skip to content

Instantly share code, notes, and snippets.

@Kyle-Ye
Created August 1, 2024 13:19
Show Gist options
  • Save Kyle-Ye/6607b0ea575590143624a235a0db6424 to your computer and use it in GitHub Desktop.
Save Kyle-Ye/6607b0ea575590143624a235a0db6424 to your computer and use it in GitHub Desktop.
SwiftUI + UIInputViewController
// Based on https://gist.github.com/liamnichols/a2e656ae93a597952b4427bcfa371185
// Add allowsSelfSizing support to support inputViewController custom height
// If you need fully dynamic height, please try https://gist.github.com/hannesoid/74ec9022021835598acf17564ce76a5a
/// `UIInputViewController` subclass that wraps a `UIHostingController` allowing you to embed SwiftUI inside `inputAccessoryViewController` and friends.
fileprivate class InputHostingViewController<Content: View>: UIInputViewController {
let hostingViewController: UIHostingController<Content>
init(rootView: Content) {
self.hostingViewController = UIHostingController(rootView: rootView)
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
class InputView: UIInputView {
var overrideHeight: CGFloat?
override func systemLayoutSizeFitting(_ targetSize: CGSize) -> CGSize {
let size = super.systemLayoutSizeFitting(targetSize)
return CGSize(width: size.width, height: overrideHeight ?? size.height)
}
}
override func loadView() {
let inputView = InputView()
inputView.overrideHeight = preferredContentSize.height
view = inputView
}
override func viewDidLoad() {
super.viewDidLoad()
guard let inputView else { return }
view.translatesAutoresizingMaskIntoConstraints = false
inputView.allowsSelfSizing = true
addChild(hostingViewController)
hostingViewController.loadViewIfNeeded()
hostingViewController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(hostingViewController.view)
NSLayoutConstraint.activate([
view.heightAnchor.constraint(equalToConstant: preferredContentSize.height)
])
NSLayoutConstraint.activate([
hostingViewController.view.topAnchor.constraint(equalTo: view.topAnchor),
hostingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
hostingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
hostingViewController.didMove(toParent: self)
}
override var preferredContentSize: CGSize {
didSet {
view.bounds.size.height = preferredContentSize.height
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment