Last active
February 27, 2023 11:23
-
-
Save matt-curtis/60d6d404912e836b04f71c4bcfffa7fd to your computer and use it in GitHub Desktop.
iOS 15 SwiftUI Keyboard Resizing (Bug?) Workaround
This file contains hidden or 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
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<ContentView> { | |
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) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment