[self.scrollView scrollRectToVisible:rect animated:YES];
没有人知道为什么它在iOS6.1和iOS7.0.4上可以很好地工作的原因,无论我发送哪种类型的rect作为参数,总是滚动到已经成为firstResponder的UITextField上。
CGRect rect = CGRectMake(0, self.scrollView.frame.size.height - 1, 320, 1);
[self.scrollView scrollRectToVisible:rect animated:YES];
由于显示在UIScrollView内的UITextField已成为iOS6.1的第一响应者,因此显示键盘时,此代码会将UIScrollView滚动至其底部,但在iOS7.0.4上,它将滚动以使UITextFiled可见。
正如我所认为的,无论如何,iOS7 SDK中的UIScrollView都会在调用scrollRectToVisible:animated:时自动滚动到它内部的第一个响应者。
将方法调用放入分配块中,这对我来说是个问题:
dispatch_async(dispatch_get_main_queue(), ^{
[self.scrollView scrollRectToVisible:rect animated:YES];
});
我不完全理解为什么这行得通,而且我不确定这是否100%安全,但另一方面,与another answer by Rikkles中建议的仅将通话延迟0.1秒相比,这要安全得多。
我还不是线程问题的专家(但是),但是当UIKeyboardDidShowNotification
发送时,似乎任何隐藏的系统方法都将覆盖滚动行为,这已经在主队列中了。因此,如果我们也将方法调用放在主队列上,那么它将在之后执行,因此会产生所需的效果。 (但这只是一个猜测。)
- (void)keyboardDidShow:(NSNotification*)aNotification {
// ... all code to choose the view you want ...
[self performSelector:@selector(moveToView:) withObject:visibleView afterDelay:0.1];
}
- (void)moveToView:(UIView *)aView {
[self.scView scrollRectToVisible:aView.frame animated:YES];
}
并且它将在操作系统自动滚动后运行,并且您真是个黄金。
[scrollView setContentSize: CGSizeMake(1, self.view.frame.size.height)];
我希望这是解决方案;)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
通知方法:
- (void) keyboardWillShow: (NSNotification*) aNotification;
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
float kbHeight = kbSize.height < kbSize.width ? kbSize.height : kbSize.width;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbHeight, 0.0);
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
}
-(void)keyboardDidShow:(NSNotification*)notification
{
CGRect aRect = CGRectMake(0, 0, _scrollView.frame.size.width, _scrollView.frame.size.height - _scrollView.frame.origin.y - self.scrollView.contentInset.bottom);
CGRect scrollFrame = CGRectMake(self.loginView.frame.origin.x + self.loginButton.frame.origin.x, self.loginView.frame.origin.y + self.loginButton.frame.origin.y, self.loginButton.frame.size.width, self.loginButton.frame.size.height);
if (!CGRectContainsRect(aRect, scrollFrame)) {
[_scrollView scrollRectToVisible:scrollFrame animated:YES];
}
}
myView
,假设您收到keyboardWillShow
时调用了UIResponder.keyboardWillShowNotification
函数。Swift 5
@objc private func keyboardWillShow(_ notification: Notification) {
if let keyboardHeight = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size.height {
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
let visibleViewFrame = myView.frame
var scrollViewFrame = scrollView.frame
scrollViewFrame.size.height -= keyboardHeight
if !scrollViewFrame.contains(visibleViewFrame) {
scrollView.setContentOffset(CGPoint(x: 0, y: visibleViewFrame.origin.y), animated: true)
}
}
}