Ios UITextView提供了不正确的插入符号rect

Ios UITextView提供了不正确的插入符号rect,ios,uitextview,Ios,Uitextview,我的UITextView代理正在使用以下命令记录插入符号位置: - (void)textViewDidBeginEditing:(UITextView *)textView { CGPoint cursorPosition = [textView caretRectForPosition:textView.selectedTextRange.start].origin; NSLog(@"cursor: %@", NSStringFromCGPoint(cursorPosition

我的UITextView代理正在使用以下命令记录插入符号位置:

- (void)textViewDidBeginEditing:(UITextView *)textView
{
    CGPoint cursorPosition = [textView caretRectForPosition:textView.selectedTextRange.start].origin;
    NSLog(@"cursor: %@", NSStringFromCGPoint(cursorPosition));
}
但报道的位置总是不准确的。具体来说,它会报告上一个光标位置-例如,如果我在文本视图内的位置(x,y)单击一次,然后在外部,然后在内部(x2,y2)单击一次,第二次单击时(x,y)坐标将被记录

事实上,selectedTextRange是问题所在-报告了上一个范围

我错过了什么?我看不到可以使用的其他委托方法。

仅当编辑刚刚开始时,selectedTextRange的值才会变老,它尚未更改。在使用选定文本计算光标位置时,旧值将导致旧位置。因此,我们需要计算不同代理中的新位置,该代理在选择更改后报告。使用下面提到的代码,您将获得正确的读数。希望能有帮助

-(void)textViewDidChangeSelection:(UITextView *)textView
{
    CGPoint cursorPosition = [textView caretRectForPosition:textView.selectedTextRange.start].origin;
    NSLog(@"cursor start: %@", NSStringFromCGPoint(cursorPosition));
}

这很糟糕,但一个解决方案是在调用方法读取之前引入一个短暂的延迟:

UITextView *textView = note.object;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    CGPoint cursorPosition = [textView caretRectForPosition:textView.selectedTextRange.start].origin;
    NSLog(@"cursor: %@", NSStringFromCGPoint(cursorPosition));
});

事实上,我找到了另一个解决办法


您可以使用
UIKeyboardDidShowNotification
获取当前选定的扩展组,而不是上一个选定的扩展组。我希望有帮助

我也有同样的问题,但是使用
UIKeyboardWillShowNotification
。在我的案例中,添加一个小延迟有助于:

func keyboardWillAppear(notification: NSNotification!) {
    dispatch_after_delay(0.01) {            
        if textView.selectedTextRange {
             // at this point range is correct 
        }
    }
}

func dispatch_after_delay(delay:NSTimeInterval, queue: dispatch_queue_t = dispatch_get_main_queue(), block: dispatch_block_t) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), queue, block)
}

这非常令人惊讶,因为委托方法是didBeginEditing,而不是willBeginEditing。你有消息来源或其他信息吗?我不能使用你建议的方法,因为它会在用户更改选择时触发,这不是我想要的。不,我没有任何关于备份的文档参考。我的主张纯粹是基于我所做的实验。但是很明显,didbeagin实际上只是指一些编辑过程的开始,这不是很明显吗。如果我们试图与UITextField代表进行类比;didBeginEditing并不意味着内容已经更改。只是我的想法:)这让我花了好几个小时才把头发拔出来。谢谢,谢谢!使用延迟也对我有用!我不知道是否还有其他解决方案,因为
textviewdibeginediting
是textView开始编辑后调用的最后一个方法@Gandalf解决方案也不错,但只有当选择与以前的选择不同时才会调用它。当收到
UIKeyboardDidShowNotification
时,启动动画就太迟了。但是,是的,在这一点上,插入符号位置的报告是正确的。@deville是的,我也喜欢延迟,因为它会立即给出正确的插入符号rect。但你可以在苹果的Notes应用程序中看到,他们使用的是
UIKeyboardDidShowNotification
(他们还使用的是UIScrollView的自动滚动功能,非常混乱),所以我认为苹果的意思是
UIKeyboardDidShowNotification
来获取插入符号rect,而在
UIKeyboardWillShowNotification
中获取不正确的插入符号rect并不是一个bug,尽管我认为他们应该修复它。