Created
August 1, 2024 13:19
-
-
Save Kyle-Ye/6607b0ea575590143624a235a0db6424 to your computer and use it in GitHub Desktop.
SwiftUI + UIInputViewController
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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