如何获取UITextField光标改变事件?

5

我正在开发 Android TV 遥控器的 iOS 版本。

我需要检测 UITextField 中光标改变的事件,并将此事件发送到 Android TV。

我找不到任何 Delegate 或 notification 可以发送 UITextfield 光标更改事件。

有没有什么办法可以获得这个事件?

非常感谢。


问题仍未解决。但我有一个解决方法。方法是监控TextField的内容。您可以将其与旧内容进行比较,然后就会知道更改点。将光标移动到该点之后。缺点是如果用户只移动光标位置而不键入任何内容,则缺乏信息。 - Chao-Yu
2个回答

4
据我所知,您可以使用KVO或子类化来实现。 由于@NSLeader已经回答了KVO的问题,我将解释后者。
以下是一个子类示例:
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) //( ͡° ͜ʖ ͡°)
    }
}

1
你很完美 :)) - Ucdemir

-1
观察 selectedTextRange 属性。
RxSwift 示例:
textField.rx.observeWeakly(UITextRange.self, "selectedTextRange")
            .observeOn(MainScheduler.asyncInstance)
            .skip(1)
            .bind { (newTextRange) in
                print(newTextRange)
            }
            .disposed(by: disposeBag)

使用RxSwift来解释会使人难以理解如何定制化UIKit以回答这个问题。 - WikipediaBrown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接