I'm working on Android TV Remote Controller - iOS version
I need to detect cursor change event in UITextField and send this event to Android TV.
I can't find any Delegate or notification will send UITextfield cursor change event.
Is there any way to get this event?
Many thanks.
As far as I know, you can KVO or subclass. Since @NSLeader gave the answer for KVO, I'll explain the latter.
Here is a subclass example:
class MyUITextFieldThatEmitsCursorChangeEvents: UITextField
{
//Override this, but don't prevent change to its default behavior by
//calling the super getter and setter.
override var selectedTextRange: UITextRange? {
get {return super.selectedTextRange}
set {
self.emitNewlySetCursor(event: newValue) //<- Intercept the value
super.selectedTextRange = newValue //Maintain normal behavior
}
}
//I'm going to use a closure to pass the cursor position out,
//but you can use a protocol, NotificationCenter, or whatever floats your
//boat.
weak var cursorPosnDidChangeEvent: ((Int) -> ())?
//I'm going to abstract the logic here to keep the previous code slim.
private func emitNewlySetCursor(event range: UITextRange?)
{
//Now you have access to the start and end in range.
//If .start and .end are different, then it means text is highlighted.
//If you only care about the position where text is about to be
//entered, then only worry about .start.
//This is an example to calculate the cursor position.
if let rawRangeComponent = range?.start
{
let cursorPosition = offset(from: beginningOfDocument,
to: rawRangeComponent)
//Emit the value to whoever cares about it
self.cursorPosnDidChangeEvent?(cursorPosition)
}
}
}
Then, for example, if we're in a UIViewController:
override func viewDidLoad()
{
super.viewDidLoad()
let tf = MyUITextFieldThatEmitsCursorChangeEvents(frame: .zero)
self.view.addSubview(tf)
tf.cursorPosnDidChangeEvent = { newCursorPosn in
print(newCursorPosn) //( ͡° ͜ʖ ͡°)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With