mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
100 lines
2.5 KiB
Swift
100 lines
2.5 KiB
Swift
import ExpoModulesCore
|
|
import UIKit
|
|
|
|
private let hardwareSubmitEventName = "onHardwareKeyboardSubmit"
|
|
|
|
private weak var activeModule: PaseoHardwareKeyboardModule?
|
|
private var isHardwareSubmitEnabled = false
|
|
|
|
@objc
|
|
public class PaseoHardwareKeyboardReactDelegateHandler: ExpoReactDelegateHandler {
|
|
public override func createRootViewController() -> UIViewController? {
|
|
return PaseoHardwareKeyboardRootViewController()
|
|
}
|
|
}
|
|
|
|
public class PaseoHardwareKeyboardModule: Module {
|
|
public func definition() -> ModuleDefinition {
|
|
Name("PaseoHardwareKeyboard")
|
|
|
|
Events(hardwareSubmitEventName)
|
|
|
|
OnCreate {
|
|
activeModule = self
|
|
}
|
|
|
|
Function("setHardwareKeyboardSubmitEnabled") { (enabled: Bool) in
|
|
DispatchQueue.main.async {
|
|
isHardwareSubmitEnabled = enabled
|
|
}
|
|
}
|
|
|
|
OnDestroy {
|
|
if activeModule === self {
|
|
activeModule = nil
|
|
}
|
|
isHardwareSubmitEnabled = false
|
|
}
|
|
}
|
|
|
|
fileprivate func emitHardwareKeyboardSubmit() {
|
|
sendEvent(hardwareSubmitEventName, [:])
|
|
}
|
|
}
|
|
|
|
private final class PaseoHardwareKeyboardRootViewController: UIViewController {
|
|
override var keyCommands: [UIKeyCommand]? {
|
|
guard isHardwareSubmitEnabled && UIDevice.current.userInterfaceIdiom == .pad else {
|
|
return super.keyCommands
|
|
}
|
|
|
|
let command = UIKeyCommand(
|
|
input: "\r",
|
|
modifierFlags: [],
|
|
action: #selector(handleHardwareKeyboardSubmit(_:))
|
|
)
|
|
if #available(iOS 15.0, *) {
|
|
command.wantsPriorityOverSystemBehavior = true
|
|
}
|
|
return (super.keyCommands ?? []) + [command]
|
|
}
|
|
|
|
@objc
|
|
private func handleHardwareKeyboardSubmit(_ sender: UIKeyCommand) {
|
|
guard canSubmitCurrentTextInput() else {
|
|
return
|
|
}
|
|
activeModule?.emitHardwareKeyboardSubmit()
|
|
}
|
|
|
|
private func canSubmitCurrentTextInput() -> Bool {
|
|
guard let responder = UIResponder.paseoCurrentFirstResponder else {
|
|
return false
|
|
}
|
|
guard let textInput = responder as? UITextInput else {
|
|
return false
|
|
}
|
|
return textInput.markedTextRange == nil
|
|
}
|
|
}
|
|
|
|
private extension UIResponder {
|
|
private static weak var currentFirstResponder: UIResponder?
|
|
|
|
static var paseoCurrentFirstResponder: UIResponder? {
|
|
currentFirstResponder = nil
|
|
UIApplication.shared.sendAction(
|
|
#selector(captureCurrentFirstResponder(_:)),
|
|
to: nil,
|
|
from: nil,
|
|
for: nil
|
|
)
|
|
return currentFirstResponder
|
|
}
|
|
|
|
@objc
|
|
private func captureCurrentFirstResponder(_ sender: Any?) {
|
|
UIResponder.currentFirstResponder = self
|
|
}
|
|
}
|