我遇到了同样的问题 - 基本上在成为第一响应者时会有延迟,不允许你改变selectedRange
任何textView*BeginEditing:
方法。如果您尝试延迟setSelectedRange:
(假设使用performSelector:withObject:afterDelay:
),它会显示出丑陋的混蛋。
解决方案实际上非常简单 - 检查委托方法的顺序会给您提示:
textViewShouldBeginEditing:
textViewDidBeginEditing:
textViewDidChangeSelection:
在最后一个方法 (3) 中设置selectedRange
可以解决问题,您只需要确保仅在UITextView
成为第一响应者时第一次重新定位光标,因为每次更新内容时都会调用方法 (3)。
shouldChangeTextInRange:
在方法 (1)、(2) 之一中设置的 BOOL 变量并检查 (3) 中的变量应该可以解决问题……只是不要忘记在重新定位后重置变量以避免常量光标重置: )。
希望能帮助到你!
编辑
经过几轮测试后,我决定设置 BOOL 标志shouldChangeTextInRange:
而不是 (2) 或 (3),因为事实证明它更通用。查看我的代码:
@interface MyClass
{
/** A flag to determine whether caret should be positioned (YES - don't position caret; NO - move caret to beginning). */
BOOL _isContentGenerated;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
// deleting
if([text length] == 0)
{
// deleting last character
if(range.length == [[textView text] length])
{
// reached beginning
/**
code to show placeholder and reset caret to the beginning
*/
_isContentGenerated = NO;
}
}
else
{
// adding
if(range.location == 0)
{
/**
code to hide placeholder
*/
_isContentGenerated = YES;
}
}
return YES;
}
- (void)textViewDidChangeSelection:(UITextView *)textView
{
if(!_isContentGenerated)
{
[textView setSelectedRange:NSMakeRange(0, 0)];
}
}