在UITextView中滚动到键盘下的插入符只有在没有动画时才有效

时间:2013-10-19 11:07:59

标签: iphone ios objective-c uiscrollview uitextview

当键盘显示并覆盖它时,我正在尝试滚动到UITextView中的插入符号。不幸的是,只有当我没有动画它时它才有效,尽管Apple在Notes应用程序中做了相同的操作。我使用的是Apple documentation中解释的相同方法。

这是代码。它位于一个独立的项目中,无需任何其他干扰即可对其进行测试。只有一个视图控制器添加了UITextView。我正在iOS 7上测试它,无论是在模拟器中还是在设备上。

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedKeyboardDidShowNotification:) name:UIKeyboardDidShowNotification object:nil];
}

- (void)receivedKeyboardDidShowNotification:(NSNotification *)notification {
    CGRect keyboardBounds = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    CGFloat keyboardDistanceFromBottomOfScreen = screenHeight - CGRectGetMinY(keyboardBounds);
    UITextView *textView = self.textView;
    UIEdgeInsets contentInset = textView.contentInset;
    contentInset.bottom += keyboardDistanceFromBottomOfScreen;
    textView.contentInset = contentInset;
    textView.scrollIndicatorInsets = contentInset;

    CGRect caretRect = [textView caretRectForPosition:textView.selectedTextRange.end];
    [textView scrollRectToVisible:caretRect animated:YES];
}

如果我将最后一行中的animated参数设置为NO,这可以很好地工作(但是没有动画,当然,我不想要)。传递YES会产生奇怪的行为。大多数情况下,视图不会滚动或滚动几个像素,但有时它会产生我想要的行为,因此结果是随机的。

我尝试计算插入符的偏移量并使用setContentOffset:animated:方法而不是scrollRectToVisible:animated:,但结果是一样的。如果animatedNO,则有效。使用YES会产生相同的奇怪结果。

更奇怪的是,在第二个解决方案中,该行的断点被击中两次,尽管通知仅发送一次。上一行或我之后添加的行上的断点(什么都不做,只是一个测试的日志语句)只被击中一次。为了增加更多的陌生感,将记录断点放在三行上产生了这个结果:

Line before
Buggy line
Line after
Buggy line

所以第二次打击就行了。看看检查员,看起来所有局部变量都不在范围内了。

我还尝试将两种解决方案的代码放在另一种方法中,并在performSelector:withObject:afterDelay:延迟后调用它,但没有任何改变,即使是长时间的延迟,如1秒。在第一个解决方案中虽然断点没有发生这种双重打击。

此时我用尽了解决方案,这对我来说似乎是一个iOS错误,但正如我所说,它在Notes应用程序中有效,所以至少有一个解决方案。

编辑:我做了一些调查,只有当文本视图是第一个响应者并且显示键盘时才会发生错误(我不能说哪个是负责人)。如果我从代码而不是键盘通知触发scrollRectToVisible:animated:,则动画可以正常工作。但是,如果我第一次调用显示键盘的[textView becomeFirstResponder],则动画会再次中断。

0 个答案:

没有答案