简体   繁体   English

UITextField 获取当前编辑的单词

[英]UITextField get currently edited word

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.如果用户返回并编辑@usertag 字符串,我想在编辑时开始自动完成。

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.我想过获取光标位置,通过“”(空格)将 nsstring 与单词分开,并计算从第一个单词到光标位置的字母。

Is there any easier way for doing that?有没有更简单的方法来做到这一点?

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];

Swift 4 Solution Swift 4解决方案

   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
    }

Here is a solution for the efficiency nerds.这是效率书呆子的解决方案。 Written in Swift 4.2 .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.我声称这更有效,因为其他答案正在调用 String 方法String.component ,该方法不必要地将整个子字符串转换为数组。 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) ?? ""
    }
}

Have you tried using UITextFieldDelegate available methods?您是否尝试过使用 UITextFieldDelegate 可用方法? 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.如果在编辑时访问单词是您想要的,您可以简单地使用-textField:shouldChangeCharactersInRange:replacementString:在此方法中,您可以访问输入的字符串,并且您还可以在此处对每个字符串进行任何字符串操作输入了新字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM