Skip to content

Instantly share code, notes, and snippets.

@lukaskubanek
Created December 4, 2023 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukaskubanek/57d0faea1de51728ceb3196667d7810f to your computer and use it in GitHub Desktop.
Save lukaskubanek/57d0faea1de51728ceb3196667d7810f to your computer and use it in GitHub Desktop.
A patch for SwiftUI views that disables keyboard avoidance
import InterposeKit
import UIKit
import SwiftUI
import SwiftUIIntrospect
extension View {
public func keyboardAvoidanceDisabled() -> some View {
self.introspect(.viewController, on: .iOS(.v17)) { viewController in
if let hostingView = viewController.parent?.view {
if String(describing: type(of: hostingView)).hasPrefix("_UIHostingView") {
hostingView.installPatchForDisablingKeyboardAvoidanceIfNeeded()
}
}
}
}
}
// https://steipete.com/posts/disabling-keyboard-avoidance-in-swiftui-uihostingcontroller/
extension UIView {
fileprivate func installPatchForDisablingKeyboardAvoidanceIfNeeded() {
guard !self.isKeyboardAvoidanceDisablingPatchInstalled else { return }
defer { self.isKeyboardAvoidanceDisablingPatchInstalled = true }
do {
try self.hook(
Selector(("keyboardWillShowWithNotification:")),
methodSignature: (@convention(c) (UIView, Selector, Notification) -> Void).self,
hookSignature: (@convention(block) (UIView, Notification) -> Void).self
) { hook in
return { _, _ in /* noop */ }
}
try self.hook(
Selector(("keyboardWillHideWithNotification:")),
methodSignature: (@convention(c) (UIView, Selector, Notification) -> Void).self,
hookSignature: (@convention(block) (UIView, Notification) -> Void).self
) { hook in
return { _, _ in /* noop */ }
}
} catch {
assertionFailure(
"""
\(UIView.self): Failed applying patch for disabling keyboard avoidance.
"""
)
}
}
}
extension UIView {
fileprivate var isKeyboardAvoidanceDisablingPatchInstalled: Bool {
get { self.getAssociatedObject(forKey: .isKeyboardAvoidanceDisablingPatchInstalled, default: false) }
set { self.setAssociatedObject(newValue, forKey: .isKeyboardAvoidanceDisablingPatchInstalled) }
}
}
extension AssociationKeys {
fileprivate static let isKeyboardAvoidanceDisablingPatchInstalled = AssociationKey<Bool>()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment