经过大量的试验和错误,我放弃了,并提出了这个问题。我见过很多人有类似的问题,但不能得到所有的答案工作正确。

我有一个由自定义单元格组成的UITableView。单元格由相邻的5个文本字段组成(有点像网格)。

当我试图滚动和编辑UITableView底部的单元格时,我不能设法让我的单元格正确地定位在键盘上方。

我看到过很多关于改变视图大小的回答……但到目前为止,没有一种效果很好。

谁能用一个具体的代码示例来阐明这样做的“正确”方式?


当前回答

如果你使用Three20,那么使用autoresizesForKeyboard属性。只要在视图控制器的-initWithNibName:bundle方法中设置

self.autoresizesForKeyboard = YES

这涉及到:

监听键盘通知并调整表视图的框架 滚动到第一个响应器

搞定了。

其他回答

我遇到了同样的问题,但注意到它只出现在一个视图中。所以我开始寻找不同的控制器。

我发现滚动行为设置在- (void)viewWillAppear:(BOOL)动画的超级实例。

所以一定要像这样实现:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // your code
}

不管你用的是UIViewController还是UITableViewController;通过将UITableView作为self的子视图来检查它。UIViewController中的视图。这是相同的行为。视图不允许滚动,如果调用[super viewWillAppear:animated];失踪了。

// scroll tableview so content ends at the middle of the tableview (out of the way of the keyboard)
CGPoint newContentOffset = CGPointMake(0, [self.tableView contentSize].height - (self.tableView.bounds.size.height / 2));
[self.tableView setContentOffset:newContentOffset animated:YES];

如果你能使用UITableViewController,你就能免费得到这个功能。然而,有时这不是一个选项,特别是当你需要多个视图而不仅仅是UITableView时。

这里介绍的一些解决方案在iOS≥4上不起作用,一些在iPad或横屏模式下不起作用,一些不适用于蓝牙键盘(我们不希望有任何滚动),一些在多个文本字段之间切换时不起作用。因此,如果您选择任何解决方案,请确保测试这些情况。这是我们在InAppSettingsKit中使用的解决方案:

- (void)_keyboardWillShow:(NSNotification*)notification {
    if (self.navigationController.topViewController == self) {
        NSDictionary* userInfo = [notification userInfo];

        // we don't use SDK constants here to be universally compatible with all SDKs ≥ 3.0
        NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"];
        if (!keyboardFrameValue) {
            keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"];
        }

        // Reduce the tableView height by the part of the keyboard that actually covers the tableView
        CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
        if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
            windowRect = IASKCGRectSwap(windowRect);
        }
        CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
        if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
            viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute);
        }
        CGRect frame = _tableView.frame;
        frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute);

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
        [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
        _tableView.frame = frame;
        [UIView commitAnimations];

        UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview;
        NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell];

        // iOS 3 sends hide and show notifications right after each other
        // when switching between textFields, so cancel -scrollToOldPosition requests
        [NSObject cancelPreviousPerformRequestsWithTarget:self];

        [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
}

- (void) scrollToOldPosition {
  [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)_keyboardWillHide:(NSNotification*)notification {
    if (self.navigationController.topViewController == self) {
        NSDictionary* userInfo = [notification userInfo];

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
        [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
        _tableView.frame = self.view.bounds;
        [UIView commitAnimations];

        [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1];
    }
}   

以下是InAppSettingsKit中该类的完整代码。要测试它,请使用“Complete List”子窗格,您可以在其中测试上面提到的场景。

以下是我如何做到这一点的,这是Sam Ho和Marcel W的回答,以及我自己对蹩脚代码的一些错误修复。我用的是UITableViewController。当键盘显示时,表格现在可以正确地调整大小。

1)在viewDidLoad我添加:

self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

2)我忘记在viewWillAppear和awakeFromNib中调用超等价物。我把这些加回来了。

在viewdidload

-(void)viewdidload{

[super viewdidload];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

    -(void)keyboardWillChange:(NSNotification*)sender{

        NSLog(@"keyboardwillchange sender %@",sender);

float margin=0  // set your own topmargin


        CGFloat originY = [[sender.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;


        if (originY >= self.view.frame.size.height){

            NSLog(@"keyboardclose");



            [tb_ setFrame:CGRectMake(0, margin, self.view.frame.size.width, self.view.frame.size.height-margin)];

        }else{

            NSLog(@"keyobard on");

            float adjustedHeight = self.view.frame.size.height - margin - (self.view.frame.size.height-originY);

            [tb_ setFrame:CGRectMake(0, margin, self.view.frame.size.width, adjustedHeight)];
        }







    }