UITextField get currently edited word

不羁的心 提交于 2019-12-21 04:59:24

问题


I'm working on an autocompletion component and I have one problem that I would like to solve in some easy way.

I want to support edits to autocompleted text, for example:

 blablabl @usertag blablabl

If user goes back and edits @usertag string, I would like to start autocompletion when it's edited.

Question is, how to get currently edited word from textfield. I thought about taking cursor position, seperate nsstring to word by " " (space) and count letters from first word to cursor position.

Is there any easier way for doing that?


回答1:


Ok I found a way to do it quite easily. Maybe someone will find it useful:

UITextRange* selectedRange = [textField selectedTextRange];
NSInteger cursorOffset = [textField offsetFromPosition:0 toPosition:selectedRange.start];
NSString* text = textField.text;
NSString* substring = [text substringToIndex:cursorOffset];
NSString* editedWord = [[substring componentsSeparatedByString:@" "] lastObject];



回答2:


Swift 4 Solution

   func getCurrentEditingWord() ->String? {
        let selectedRange: UITextRange? = self.textView.selectedTextRange
        var cursorOffset: Int? = nil
        if let aStart = selectedRange?.start {
            cursorOffset = self.textView.offset(from: self.textView.beginningOfDocument, to: aStart)
        }
        let text = self.textView.text
        let substring = (text as NSString?)?.substring(to: cursorOffset!)
        let editedWord = substring?.components(separatedBy: " ").last
        return editedWord
    }



回答3:


Here is a solution for the efficiency nerds. Written in Swift 4.2. I'm claiming that is is more efficient because other answers are calling the String method String.component which unnecessarily converts the entire substring to an array. Also those solutions are always grabbing words before the cursor which may not necessarily be the current word.

extension UITextView {
    /// Returns the current word that the cursor is at.
    func currentWord() -> String {
        guard let cursorRange = self.selectedTextRange else { return "" }
        func getRange(from position: UITextPosition, offset: Int) -> UITextRange? {
            guard let newPosition = self.position(from: position, offset: offset) else { return nil }
            return self.textRange(from: newPosition, to: position)
        }

        var wordStartPosition: UITextPosition = self.beginningOfDocument
        var wordEndPosition: UITextPosition = self.endOfDocument

        var position = cursorRange.start

        while let range = getRange(from: position, offset: -1), let text = self.text(in: range) {
            if text == " " || text == "\n" {
                wordStartPosition = range.end
                break
            }
            position = range.start
        }

        position = cursorRange.start

        while let range = getRange(from: position, offset: 1), let text = self.text(in: range) {
            if text == " " || text == "\n" {
                wordEndPosition = range.start
                break
            }
            position = range.end
        }

        guard let wordRange = self.textRange(from: wordStartPosition, to: wordEndPosition) else { return "" }

        return self.text(in: wordRange) ?? ""
    }
}



回答4:


Have you tried using UITextFieldDelegate available methods? If access to the word as you edit it is what you want, you can simply use the -textField:shouldChangeCharactersInRange:replacementString: Inside this method you have access to the string as it's entered, and you can also do any string manipulation here for every new character entered.



来源:https://stackoverflow.com/questions/22507884/uitextfield-get-currently-edited-word

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!