如何在UITextView粘贴时去除号码前缀tel:?
解决iPhone Notes复制号码到UITextView自动添加tel:前缀的问题
我之前也踩过这个坑!Notes里复制的号码粘贴后会自动带上tel:前缀,而且你用shouldChangeTextInRange修改参数里的text根本没用——因为这个方法里的replacementText是系统传过来的局部变量,你修改它不会影响系统实际执行粘贴的内容,系统还是会用原来的字符串去替换。
问题原因分析
从Notes复制的号码本质上是带URL Scheme的结构化数据,粘贴时系统会自动把它转换成tel:开头的字符串;而从Contacts或Safari复制的是纯文本,所以不会触发这个转换。shouldChangeTextInRange的设计只是让你判断是否允许文本修改,修改参数里的text不会改变系统要粘贴的原始内容。
两种可行的解决方案
方案一:在文本变化后过滤(简单直接)
用textViewDidChange代理方法,在文本已经粘贴完成后检查并替换掉tel:前缀:
- (void)textViewDidChange:(UITextView *)textView { if (textView == destination) { NSString *originalText = textView.text; NSString *cleanedText = [originalText stringByReplacingOccurrencesOfString:@"tel:" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, originalText.length)]; // 只有内容变化时才修改,避免无限触发textViewDidChange if (![cleanedText isEqualToString:originalText]) { textView.text = cleanedText; } } }
方案二:用粘贴代理提前处理(更优雅高效)
使用UITextPasteDelegate,在粘贴过程中直接处理原始内容,从根源上过滤掉tel:前缀:
- 先给目标UITextView设置粘贴代理:
destination.pasteDelegate = self;
- 实现代理方法,处理粘贴项:
- (NSArray<UITextPasteItem *> *)textPasteConfigurationSupporting:(id<UITextPasteConfigurationSupporting>)textPasteConfigurationSupporting transformPasteItems:(NSArray<UITextPasteItem *> *)pasteItems { if (textPasteConfigurationSupporting == destination) { for (UITextPasteItem *item in pasteItems) { [item setResultProvider:^UITextPasteItemResult * _Nullable(UITextPasteItem * _Nonnull item) { // 同步加载粘贴的字符串内容 id loadedValue = [item.itemProvider loadObjectOfClass:[NSString class] completionHandler:nil]; if ([loadedValue isKindOfClass:[NSString class]]) { NSString *pastedText = (NSString *)loadedValue; // 检查并移除tel:前缀 if ([pastedText hasPrefix:@"tel:"]) { NSString *cleanedText = [pastedText stringByReplacingOccurrencesOfString:@"tel:" withString:@""]; return [[UITextPasteItemResult alloc] initWithType:UITextPasteTypeString string:cleanedText]; } } // 非tel:开头的内容,返回原始粘贴项 return [[UITextPasteItemResult alloc] initWithItemProvider:item.itemProvider type:UITextPasteTypeString]; }]; } } return pasteItems; }
为什么原来的方法无效?
再强调下:shouldChangeTextInRange里的replacementText是系统传递的不可修改的输入参数(你修改的只是局部变量副本),系统在执行粘贴逻辑时,用的还是最初传入的那个字符串,所以你的修改不会生效。
内容的提问来源于stack exchange,提问作者MMSmmsbd
相关产品推荐
相关产品推荐

