键盘会显示通知,但键盘窗口为零

时间:2014-10-27 07:15:56

标签: ios iphone keyboard

我有点困惑。我正在创建一个应用程序,用户可以在页面之间水平滑动滚动视图,每个页面都有文本字段或文本视图。我订阅了UIKeyboardWillShowNotification和UIKeyboardWillHideNotification通知,并且当键盘弹出时卡会降低它们的高度,并在键盘隐藏时将其增加。 此外,当拖动scrollView时,所有textViews / textField都会重新响应第一个响应者。这就是它的样子:

-(void)keyboardWillHide:(NSNotification*)notification{
//    NSLog(@"notification user info = %@",notification.userInfo);
    auto userInfo=notification.userInfo;
    auto curve=[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
    auto duration=[userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    auto startFrame=[userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    auto endFrame=[userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    auto dY=endFrame.origin.y-startFrame.origin.y;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:(UIViewAnimationCurve)curve];
    [UIView setAnimationDuration:duration];
    _feedbackTextView.height+=dY;
    _feedbackUserDataView.height+=dY;
    [UIView commitAnimations];
}

-(void)keyboardWillShow:(NSNotification *)notification{
//    NSLog(@"notification user info = %@",notification.userInfo);
    auto userInfo=notification.userInfo;
    auto curve=[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
    auto duration=[userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    auto startFrame=[userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    auto endFrame=[userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    auto dY=endFrame.origin.y-startFrame.origin.y;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:(UIViewAnimationCurve)curve];
    [UIView setAnimationDuration:duration];
    _feedbackTextView.height+=dY;
    _feedbackUserDataView.height+=dY;
    [UIView commitAnimations];
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    [_feedbackTextView resignFirstResponder];
    [_feedbackUserDataView resignFirstResponder];
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
//    NSLog(@"%s",sel_getName(_cmd));
    CGFloat width = scrollView.frame.size.width;
    NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;
    switch(page){
        case 0:{
            [_feedbackTextView becomeFirstResponder];
        }break;
        case 1:{
            [_feedbackUserDataView becomeFirstResponder];
        }break;
    }
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
//    NSLog(@"decelerate = %d",decelerate);
    if(decelerate==NO){
        CGFloat width = scrollView.frame.size.width;
        NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;
        switch(page){
            case 0:{
                [_feedbackTextView becomeFirstResponder];
            }break;
            case 1:{
                [_feedbackUserDataView becomeFirstResponder];
            }break;
        }
    }
}

_feedbackTextView是scrollView第一页上的子视图,_feedbackUserDataView是scrollView第二页上的子视图。 我测试了我的App。我滚动,混乱地点击textViews / textFields。我在日志中收到警告

|warning| Got a keyboard will show notification, but keyboard window is nil.

令我惊讶的是谷歌没有任何相关内容所以我在这里发了一个问题。抱歉丑陋的格式化。

1 个答案:

答案 0 :(得分:1)

在动画完成之前,键盘在呈现后立即被解除时,似乎会产生此警告。

在这种情况下,当用户在滚动视图仍在减速时再次开始平移时,可以调用scrollViewDidEndDecelerating:。然后立即调用scrollViewDidScroll:,这会导致键盘被呈现并立即被解除。

一个修复方法是检查scrollView的panGestureRecogniser状态,如果它在UIGestureRecognizerStateBegan

中,则避免使文本字段成为第一响应者
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    if ([scrollView panGestureRecognizer].state == UIGestureRecognizerStateBegan) {
        return;
    }

    //    NSLog(@"%s",sel_getName(_cmd));
    CGFloat width = scrollView.frame.size.width;
    NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;
    switch(page){
        case 0:{
            [_feedbackTextView becomeFirstResponder];
        }break;
        case 1:{
            [_feedbackUserDataView becomeFirstResponder];
        }break;
    }
}

这应删除大部分警告。如果用户在呈现键盘时开始平移,可能仍会有一些。这些将更难处理 - 您需要确保键盘已经完成它的演示动画,然后通过订阅UIKeyboardDidShowNotification并在用户正在平移时将其解雇而解除它。