我正在开发 Android TV 遥控器的 iOS 版本。
我需要检测 UITextField 中光标改变的事件,并将此事件发送到 Android TV。
我找不到任何 Delegate 或 notification 可以发送 UITextfield 光标更改事件。
有没有什么办法可以获得这个事件?
非常感谢。
我正在开发 Android TV 遥控器的 iOS 版本。
我需要检测 UITextField 中光标改变的事件,并将此事件发送到 Android TV。
我找不到任何 Delegate 或 notification 可以发送 UITextfield 光标更改事件。
有没有什么办法可以获得这个事件?
非常感谢。
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)
}
}
}
例如,如果我们在一个UIViewController中:
override func viewDidLoad()
{
super.viewDidLoad()
let tf = MyUITextFieldThatEmitsCursorChangeEvents(frame: .zero)
self.view.addSubview(tf)
tf.cursorPosnDidChangeEvent = { newCursorPosn in
print(newCursorPosn) //( ͡° ͜ʖ ͡°)
}
}
selectedTextRange
属性。textField.rx.observeWeakly(UITextRange.self, "selectedTextRange")
.observeOn(MainScheduler.asyncInstance)
.skip(1)
.bind { (newTextRange) in
print(newTextRange)
}
.disposed(by: disposeBag)