-
-
Save wearhere/f46ab9d837acaeaabfa86a813c44ad25 to your computer and use it in GitHub Desktop.
| // | |
| // documentProxy.swift | |
| // KeyboardKitDemoKeyboard | |
| // | |
| // Created by Jeffrey Wear on 4/28/20. | |
| // | |
| import UIKit | |
| class TextDocumentProxy<TextDocument: UIResponder & UITextInput>: NSObject, UITextDocumentProxy { | |
| init(document: TextDocument) { | |
| self.document = document | |
| super.init() | |
| } | |
| private unowned let document: TextDocument | |
| // MARK: - UITextDocumentProxy | |
| var documentInputMode: UITextInputMode? { | |
| document.textInputMode | |
| } | |
| var documentContextAfterInput: String? { | |
| guard let selectedTextRange = document.selectedTextRange else { | |
| return nil | |
| } | |
| guard let rangeAfterInput = document.textRange(from: selectedTextRange.end, to: document.endOfDocument) else { | |
| return nil | |
| } | |
| return document.text(in: rangeAfterInput) | |
| } | |
| var documentContextBeforeInput: String? { | |
| guard let selectedTextRange = document.selectedTextRange else { | |
| return nil | |
| } | |
| guard let rangeBeforeInput = document.textRange(from: document.beginningOfDocument, to: selectedTextRange.start) else { | |
| return nil | |
| } | |
| return document.text(in: rangeBeforeInput) | |
| } | |
| // https://stackoverflow.com/a/41023439/495611 suggests adjusting the text | |
| // position (i.e. moving the cursor) by adjusting the selected text range. | |
| func adjustTextPosition(byCharacterOffset offset: Int) { | |
| guard let selectedTextRange = document.selectedTextRange else { return } | |
| // Not sure what's supposed to happen if the range is non-empty. Let's | |
| // abort if it is. | |
| guard selectedTextRange.isEmpty else { return } | |
| // Now that it's empty, the start and end should be the same. Move that position. | |
| // The guard is a bounds check. | |
| guard let newPosition = document.position(from: selectedTextRange.start, offset: offset) else { return } | |
| document.selectedTextRange = document.textRange(from: newPosition, to: newPosition) | |
| } | |
| var selectedText: String? { | |
| guard let selectedTextRange = document.selectedTextRange else { | |
| return nil | |
| } | |
| return document.text(in: selectedTextRange) | |
| } | |
| let documentIdentifier: UUID = UUID() | |
| func setMarkedText(_ markedText: String, selectedRange: NSRange) { | |
| document.setMarkedText(markedText, selectedRange: selectedRange) | |
| } | |
| func unmarkText() { | |
| document.unmarkText() | |
| } | |
| // MARK: - UIKeyInput | |
| func insertText(_ text: String) { | |
| document.insertText(text) | |
| } | |
| func deleteBackward() { | |
| document.deleteBackward() | |
| } | |
| var hasText: Bool { | |
| document.hasText | |
| } | |
| } | |
Thanks @danielsaidi for Reply
No, I didn't use KeyboardKit Pro.
I just tested your demo code.
In my custom keyboard, I used textDocumentProxy.documentContextBeforeInput, but it can't read more than 300 characters — unlike your fullDocumentContext, which reads all the text.
How can I handle large text like that? without using KeyboardKit Pro?
I see, yes the native text document proxy APIs have always been very lacking.
The full document context implementation is a Pro feature with a lot of time and effort put into it. You need a Silver license to use it. Without KeyboardKit Pro, you have to implement the logic yourself.
Best,
Daniel
@danielsaidi I respect your effort and time.
However, I am a student and don't have the budget to purchase a Silver license.
I only need this one feature to implement in my code, as it's currently blocking my app's progress.
If you could offer some support, I would be very grateful.
Hi @saqlainjamil5
Are you trying to use KeyboardKit Pro's
fullDocumentContextfeature?