Swift 4字符串替换:UITextField与TableView@提及用户功能异常排查
解决@提及功能仅识别最后一个词的问题
我来帮你搞定这个@提及的问题!目前你的代码逻辑是把整个文本按空格拆分后取最后一个词来判断是否带@,这就导致只有当@开头的词是文本末尾的内容时才会触发推荐——但实际场景中用户很可能在文本中间插入@提及,这时候你的逻辑就失效了。
问题根源
你的这段代码只关注了整个文本的最后一个词:
let caption = captionTextView.text let words = caption?.components(separatedBy: .whitespacesAndNewlines) guard let searchingWord = words?.last else {return}
比如用户输入"Hey @alice, let's tag @bob",当输入到@bo的时候,整个文本的最后一个词是@bo吗?不,此时文本是"Hey @alice, let's tag @bo",按空格拆分后最后一个词是@bo,这时候没问题,但如果用户是在@alice后面直接继续输入@charlie(比如修改文本为"Hey @alice@charlie"),或者在中间位置插入@,你的逻辑就抓不到正确的搜索词了。
解决方案:基于光标位置提取当前输入的@词
正确的思路应该是获取光标所在位置之前的文本,找到当前正在输入的那个@开头的词,而不是整个文本的最后一个词。下面是调整后的代码:
// 1. 获取光标位置和到光标处的文本 let cursorPosition = captionTextView.selectedRange.location guard let caption = captionTextView.text, cursorPosition <= caption.count else { self.indicator.stopAnimating() return } let substringToCursor = caption.prefix(cursorPosition) // 2. 拆分到光标处的文本,取最后一个词判断是否带@ let words = substringToCursor.components(separatedBy: .whitespacesAndNewlines) guard let searchingWord = words.last, searchingWord.hasPrefix("@") else { // 如果没有正在输入的@词,停止指示器并隐藏推荐列表 self.indicator.stopAnimating() self.recommendedUsersTableView.isHidden = true return } // 3. 执行你的搜索逻辑 self.indicator.startAnimating() // 去掉@和可能的标点,得到纯搜索关键词 let searchQuery = searchingWord.trimmingCharacters(in: CharacterSet.punctuationCharacters).dropFirst() // 这里调用你的搜索接口,用searchQuery获取推荐用户
进阶优化:用正则更精准匹配@词
如果需要支持更复杂的场景(比如@词后面跟标点、或者非空格分隔的输入),可以用正则表达式来精准匹配光标前最后一个@开头的词:
let cursorPosition = captionTextView.selectedRange.location guard let caption = captionTextView.text, cursorPosition <= caption.count else { self.indicator.stopAnimating() return } let substringToCursor = caption.prefix(cursorPosition) // 匹配@开头,直到遇到空格或标点的词 do { let regex = try NSRegularExpression(pattern: "@[\\w]+$", options: []) let range = NSRange(substringToCursor.startIndex..., in: caption) if let match = regex.firstMatch(in: caption, options: [], range: range) { let searchingWord = (caption as NSString).substring(with: match.range) let searchQuery = searchingWord.dropFirst() // 去掉@符号 self.indicator.startAnimating() // 执行搜索逻辑 } else { self.indicator.stopAnimating() self.recommendedUsersTableView.isHidden = true } } catch { print("正则表达式错误:\(error)") }
这样不管用户在文本的哪个位置输入@开头的词,只要光标停在这个词的末尾,就能正确触发推荐功能啦!
内容的提问来源于stack exchange,提问作者Zash__
相关产品推荐
相关产品推荐

