如何在UITableView中测试键盘是否覆盖UITextField?

时间:2013-10-06 16:26:20

标签: ios objective-c ipad cocoa-touch uitableview

如何检查键盘是否覆盖UIScrollView内的第一响应者,可能是UITableView还是UIScrollView?请注意,UIModalPresentationFormSheet不一定会涵盖整个viewController的视图,并且可能包含在模态视图中(CGRectContainsPoint)。

我正在使用来自Apple's reference documentation and example的修改后的代码,但即使键盘明显覆盖了第一个响应者,convertRect:toView也会返回false。很明显,我没有正确使用- (void)keyboardWasShown:(NSNotification*)aNotification { // self.scrollView can be a tableView or not. need to handle both UIView *firstResponderView = [self.scrollView findFirstResponder]; if (!firstResponderView) return; NSDictionary* info = [aNotification userInfo]; CGRect rect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; // convertRect:toView? convertRect:fromView? Always confusing CGRect kbRect = [self.scrollView convertRect:rect toView:nil]; CGRect viewRect = [self.scrollView convertRect:firstResponderView.bounds toView:nil]; // doesn't work. convertRect misuse is certainly to blame if (!CGRectContainsPoint(kbRect, firstResponderView.frame.origin)) return; // Only inset to the portion which the keyboard covers? UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbRect.size.height, 0.0); self.scrollView.contentInset = contentInsets; self.scrollView.scrollIndicatorInsets = contentInsets; }

此外,Apple的代码没有考虑到视图不是全屏,因此将scrollView的contentInset设置为键盘的整个高度并不是一个很好的解决方案 - 它应该只是插入部分键盘覆盖第一个响应者。

{{1}}

1 个答案:

答案 0 :(得分:2)

如果没有进一步测试或深入研究逻辑,这条线似乎很奇怪:

CGRect kbRect = [self.scrollView convertRect:rect toView:nil];

键盘rect(包含在通知中)位于 window 坐标中,您可能希望将其转换为滚动视图坐标系。 [viewA convertRect:rect toView:viewB]将rect从viewA的坐标系转换为viewB的坐标系,所以你实际上正在做你应该做的事情(正如你所怀疑的那样)。

我通常做的是:

- (void)keyboardWillShow:(NSNotification *)aNotification
{
    NSDictionary *info = [aNotification userInfo];
    CGRect kbRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    kbRect = [self.view.window convertRect:kbRect toView:self.view];    // convert to local coordinate system, otherwise it is in window coordinates and does not consider interface orientation
    _keyboardSize = kbRect.size;    // store for later use

    [UIView animateWithDuration:0.25 animations:^{
        UIEdgeInsets insets = UIEdgeInsetsMake(0.0f, 0.0f, MAX(0.0f, CGRectGetMaxY(_tableView.frame) - CGRectGetMinY(kbRect)), 0.0f);    // NB: _tableView is a direct subview of self.view, thus _tableView.frame and kbRect are in the same coordinate system
        _tableView.contentInset = insets;
        _tableView.scrollIndicatorInsets = insets;
        [self scrollToActiveTextField];    // here I adapt the content offset to ensure that the active text field is fully visible
    }];
}