当键盘显示并覆盖它时,我正在尝试滚动到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:
,但结果是一样的。如果animated
为NO
,则有效。使用YES
会产生相同的奇怪结果。
更奇怪的是,在第二个解决方案中,该行的断点被击中两次,尽管通知仅发送一次。上一行或我之后添加的行上的断点(什么都不做,只是一个测试的日志语句)只被击中一次。为了增加更多的陌生感,将记录断点放在三行上产生了这个结果:
Line before
Buggy line
Line after
Buggy line
所以第二次打击就行了。看看检查员,看起来所有局部变量都不在范围内了。
我还尝试将两种解决方案的代码放在另一种方法中,并在performSelector:withObject:afterDelay:
延迟后调用它,但没有任何改变,即使是长时间的延迟,如1秒。在第一个解决方案中虽然断点没有发生这种双重打击。
此时我用尽了解决方案,这对我来说似乎是一个iOS错误,但正如我所说,它在Notes应用程序中有效,所以至少有一个解决方案。
编辑:我做了一些调查,只有当文本视图是第一个响应者并且显示键盘时才会发生错误(我不能说哪个是负责人)。如果我从代码而不是键盘通知触发scrollRectToVisible:animated:
,则动画可以正常工作。但是,如果我第一次调用显示键盘的[textView becomeFirstResponder]
,则动画会再次中断。