• 要解决的问题

在输入框中,需要整体删除诸如 “xxx@xx.com” 或 “@xxxx” 等文本

  • 实现思路

在删除动作时,获取到当前光标的位置,如果在光标正在处在上述文本范围内,就删除一整串文本

  • 如何实现 (仅用 UITextField 示例, UITextView 实现原理是一样的)
  1. 为 UITextField 的 UITextFieldDelegate 实现  - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;  方法,在这个方法里面,当 replacementString 返回来的长度是 0 时,即表示输入了删除键,这样我们知道了删除动作的时机。
  2. 获取删除时的光标位置,光标位置是个相对位置,可以是相对于输入框文本的 begin 位置或者是 end 位置,这里取相当于 begin 的位置 NSInteger cursorOffset = [textField offsetFromPosition:textField.beginningOfDocument toPosition:textField.selectedTextRange.start];
  3. 判断是否在目标字符串的范围内,如果是,就删除整个目标字符串
  4. 第3步的删除动作完成后,将光标移动到删除时的位置
  • 代码示例

整个过程的关键,就是对 textField:shouldChangeCharactersInRange:replacementString 的实现。代码如下

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (string.length != ) {
return YES;
}
if (self.quoteText.length == ) { // quoteText 就是目标字符串
return YES;
}
// 计算当前光标相对于文本开始位置的偏移量
NSInteger cursorOffset = [textField offsetFromPosition:textField.beginningOfDocument toPosition:textField.selectedTextRange.start]; NSRange foundRange = [textField.text rangeOfString:self.quoteText];
if (foundRange.location != NSNotFound) {
if (foundRange.location <= cursorOffset &&
foundRange.length + foundRange.location >= cursorOffset) { textField.text = [textField.text stringByReplacingCharactersInRange:foundRange withString:@""];
// 光标移动到删除时的位置
UITextPosition *beginPosition = [textField positionFromPosition:textField.beginningOfDocument offset:foundRange.location];
UITextRange *newRange = [textField textRangeFromPosition:beginPosition toPosition:beginPosition];
[textField setSelectedTextRange:newRange]; return NO;
}
return YES;
} else {
return YES;
}
}
  • 更多

    • 如果需求比较复杂,比如类似 iMessage、Mail 的输入联系人时的删除绑定效果,推荐使用 YYTextView (来自 GitHub: YYText
    • 由于 UITextField 实现了 UITextInput 协议, UITextInput 协议继承自 UIKeyInput,UIKeyInput 中有 @required 的方法 - (void)deleteBackward; 可以直接拿到删除事件,所以也可以从这方面去着手处理删除绑定

最新文章

  1. Asp.Net WebForm和MVC同样优秀!
  2. 【POJ 1182】食物链(并查集)
  3. Spring整合Hibernate。。。。
  4. python--数据清洗
  5. Linux中查看进程的多线程pstree, ps -L
  6. C#的SerialPort串口程序设计总结
  7. 使用Maven管理依赖JAR文件,自定义项目布局,利用ANT生成不同的发布包
  8. Problem J: 求个最大值
  9. Extjs6 grid 导出excel功能类,支持renderer
  10. docker镜像的常用操作
  11. 【BZOJ3653】谈笑风生(长链剖分)
  12. type的解释
  13. kraken-ejs创建一个项目【学习札记】
  14. vue--自定义验证指令
  15. WPF 背景颜色渐变的滑动条实现
  16. javaweb(六)——Servlet开发(二)
  17. nodejs基础学习
  18. django配置文件环境分离后celery的启动方式整理
  19. log4j方法的使用
  20. 【29】html5新标签有哪些?

热门文章

  1. 【Vue】---- 手动封装on,emit,off
  2. MATLAB神经网络(2)之R练习
  3. h5微信中视频禁止全屏
  4. 为什么vue中的data用return返回呢?
  5. Docker Compose 文件讲解
  6. Java-正则表达式(新手)
  7. 在linux系统中安装LANMP
  8. 从发布订阅模式入手读懂Node.js的EventEmitter源码
  9. 14. LiveBos编号自动生成
  10. 2000字读懂Java的来源