textView:shouldChangeTextInRange:replacementText: 返回 NO,但自动更正忽略?
Posted
技术标签:
【中文标题】textView:shouldChangeTextInRange:replacementText: 返回 NO,但自动更正忽略?【英文标题】:textView:shouldChangeTextInRange:replacementText: returning NO, but autocorrect ignores? 【发布时间】:2014-01-08 21:41:07 【问题描述】:我遇到以下问题,不确定这是否是 ios 错误,或者我误解了 UITextViewDelegate 回调。只有当我使用软件键盘(即使用鼠标单击屏幕键盘)时,我才能在我的设备(iPad Retina)和模拟器上重现此行为。
考虑以下人为设计的示例项目(2014 年 1 月 9 日更新): https://www.dropbox.com/s/1q3vqfnsmmbhnuj/AutocorrectBug.zip
这是一个简单的 UITextView,将视图控制器设置为其委托,具有以下委托方法:
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
if ([text isEqualToString:@" "]
&& range.length == 0
&& (range.location == 0
|| [[textView.text substringWithRange:NSMakeRange(range.location-1, 1)] isEqualToString:@"\n"]))
textView.backgroundColor = [UIColor yellowColor];
return NO;
return YES;
我对这段代码的意图是,当用户键入一个空格(编辑:并且该空格是该行的第一个字符)时,该空格被忽略,而是发生了一些其他功能,在这种情况下 UITextView 会变黄。
现在考虑以下步骤:
-
点击文本视图使其成为第一响应者
输入“Apple”,按回车键并记下定位
现在,输入一个空格(将文本视图变为黄色),再次输入“Apple”并回车。
预期:黄色背景和文字阅读:
Apple
Apple
观察到:黄色背景和文字阅读(由于自动更正):
Apple
Apple
似乎自动更正逻辑忽略了 textView:shouldChangeTextInRange:replacementText: 的结果。
这是预期行为吗? 如果可以,是否可以解决?编辑 1/9/14:只应忽略一行中的第一个空格,其他空格应正常处理(即插入到文本中),排除蛮力的空格条。此外,我正在文本编辑器中处理一个大字符串(可能有数十万个字符)(意味着不断的用户输入),因此每次击键都分析整个字符串不会高效。 p>
【问题讨论】:
您是否会考虑禁用该 UITextField 的自动更正功能。为其设置 autocorrectionType。 @RaymondBrion 如果可能,我想避免使用该解决方案,否则此处需要自动更正。 【参考方案1】:是的,我在 iPad 7.0.3 模拟器上也看到了。
解决它的一种方法是添加这个UITextViewDelegate
方法:
- (void)textViewDidChange:(UITextView *)textView
// eliminates spaces, including those introduced by autocorrect
if ([textView.text rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]].location != NSNotFound)
textView.text = [textView.text stringByReplacingOccurrencesOfString:@" " withString:@""];
更新
似乎这个委托方法是在自动更正之后调用的,只是在你想要阻止的情况下(“Apple”变成“Apple”)替换文本是“Apple”而不是“”。因此,要修改实现以防止“\n”但允许文本中出现其他“”字符,您可以尝试将text
的第一个字符与“”进行比较,而不是将text
与“”进行比较。
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
// compare first character to 'space' character by decimal value
if (text.length && [text characterAtIndex:0] == 32)
// check if previous character is a newline
NSInteger locationOfPreviousCharacter = range.location - 1;
if (locationOfPreviousCharacter < 0 || [textView.text characterAtIndex:locationOfPreviousCharacter] == 10)
textView.backgroundColor = [UIColor yellowColor];
return NO;
return YES;
【讨论】:
+1 以获得完全有效的解决方案;但是它告诉我我的问题措辞错误。正如我所描述的那样,只有一行上的第一个空格应该被忽略,同一行上的其他空格应该被视为正常。此外,我正在处理非常大的字符串(多达数十万个字符),因此分析每个键入的字母的整个字符串不会很高效。 这行得通。将仅替换第一次出现的字符串 NSRange location = [text rangeOfString:@" "]; NSString* 结果 = [someString stringByReplacingCharactersInRange:location withString:text]; textView.text = 结果; 我明白了...您是否还意味着只有当它们是一行中的第一个 字符 时才应删除空格?这样如果第一个空格不是其行中的第一个字符,它也应该被忽略?以上是关于textView:shouldChangeTextInRange:replacementText: 返回 NO,但自动更正忽略?的主要内容,如果未能解决你的问题,请参考以下文章