Uitableview iOS 5:在文本字段之间跳转时的奇怪行为

Uitableview iOS 5:在文本字段之间跳转时的奇怪行为,uitableview,ios5,uitextfield,Uitableview,Ios5,Uitextfield,在我的应用程序中,我有一个相当大的表格要填写。表单本身由表视图和静态单元格模式组成。包含标签和文本字段的每个单元格。我想在键盘上方添加一个工具栏,以便在文本字段之间导航。我这样做了,但它的行为非常奇怪(至少我认为) 我跳到下一个文本字段没有问题,而跳到上一个文本字段只有在它可见时才可能。如果不可见,则旧的文本字段将保留为第一响应者,但当我滚动表格视图并显示预期的文本字段时,它将成为第一响应者(我不会点击它!)。这当然不是我想要的行为 我的问题是:这种行为正常吗?你能绕过它吗 如果你想亲眼看到这种

在我的应用程序中,我有一个相当大的表格要填写。表单本身由表视图和静态单元格模式组成。包含标签和文本字段的每个单元格。我想在键盘上方添加一个工具栏,以便在文本字段之间导航。我这样做了,但它的行为非常奇怪(至少我认为)

我跳到下一个文本字段没有问题,而跳到上一个文本字段只有在它可见时才可能。如果不可见,则旧的文本字段将保留为第一响应者,但当我滚动表格视图并显示预期的文本字段时,它将成为第一响应者(我不会点击它!)。这当然不是我想要的行为

我的问题是:这种行为正常吗?你能绕过它吗

如果你想亲眼看到这种行为,我上传了一个Xcode项目来说明这个问题。您可以在此处下载压缩的项目:。代码的主要部分解释如下

我用静态单元格设置了一个分组表视图。它们中的每一个都包含一个标签和一个
textfield
。我为每个文本字段创建了出口以访问它们。在viewDidLoad方法中,我创建工具栏及其按钮,将textfields存储在数组中,并将控制器设置为textfields代理

- (void)viewDidLoad
{
    [super viewDidLoad];

    // create the keyboard toolbar with navigation elements
    self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];

    UIBarButtonItem *prevButton = [[UIBarButtonItem alloc] initWithTitle:@"Previous" style:UIBarButtonItemStyleBordered target:self action:@selector(prevClicked:)];
    UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStyleBordered target:self action:@selector(nextClicked:)];

    [self.keyboardToolbar setItems:[NSArray arrayWithObjects:prevButton, nextButton, nil]];


    // create the field chain
    self.fields = [NSArray arrayWithObjects:self.aField, self.bField, self.cField, self.dField, self.eField, self.fField, nil];

    // for scrolling and keeping track of currently active field
    NSInteger max = [self.fields count];
    for(NSInteger i = 0; i < max; i++) {
        UITextField *curr = (UITextField *)[self.fields objectAtIndex:i];
        curr.delegate     = self;
    }
}
最后是工具栏按钮的选择器和获取下一个文本字段的逻辑

- (void)moveResponderByStep:(NSInteger)step
{
    // only move if a textfield is the current responder
    if(![self.currentField isEditing]) {
        return;
    }

    // where we are and where to move
    NSInteger max = [self.fields count];
    NSInteger moveToNumber;

    for(NSInteger i = 0; i < max; i++) {
        if(self.currentField == [self.fields objectAtIndex:i]) {
            moveToNumber = i + step;
        }
    }

    // stay in bounds
    if(moveToNumber >= max || moveToNumber < 0) {
        [self.currentField resignFirstResponder];
        return;
    }

    // move on
    UITextField *next = [self.fields objectAtIndex:moveToNumber];
    [next becomeFirstResponder];

}

- (void)prevClicked:(id)sender
{
    [self moveResponderByStep:-1];
}

- (void)nextClicked:(id)sender
{
    [self moveResponderByStep:1];
}
-(void)moveResponderByStep:(NSInteger)步骤
{
//仅当文本字段是当前响应者时才移动
如果(![self.currentField isEditing]){
回来
}
//我们在哪里,我们要去哪里
NSInteger max=[self.fields count];
NSInteger moveToNumber;
对于(NSInteger i=0;i=max | |移动编号<0){
[self.currentField resignFirstResponder];
回来
}
//继续
UITextField*next=[self.fields objectAtIndex:moveToNumber];
[下一步成为第一响应者];
}
-(无效)已单击:(id)发件人
{
[自移动应答器步骤:-1];
}
-(无效)下一个勾选:(id)发件人
{
[自移动应答器步:1];
}

谢谢大家!

首先尝试检查该行是否可见。如果行不可见,则滚动该行。然后将文本字段设置为first responder。

尝试先检查该行是否可见。如果行不可见,则滚动该行。然后将文本字段设置为first responder。

在更改first responder之前,是否尝试滚动表格视图以使上一个单元格可见。谢谢@dasdom和rob。我应该说我试过了。问题是,如果单元格不可见,indexPathForCell将返回null。在我的应用程序中,并非每一行都包含一个文本字段,因此我必须跟踪它们在其他地方的位置。当然可以,但我认为这不是一个理想的解决方案。在更改第一响应程序之前,您是否尝试滚动表格视图以使上一个单元格可见。谢谢@dasdom和rob。我应该说我试过了。问题是,如果单元格不可见,indexPathForCell将返回null。在我的应用程序中,并非每一行都包含一个文本字段,因此我必须跟踪它们在其他地方的位置。当然,在我看来,这不是一个理想的解决方案。
- (void)moveResponderByStep:(NSInteger)step
{
    // only move if a textfield is the current responder
    if(![self.currentField isEditing]) {
        return;
    }

    // where we are and where to move
    NSInteger max = [self.fields count];
    NSInteger moveToNumber;

    for(NSInteger i = 0; i < max; i++) {
        if(self.currentField == [self.fields objectAtIndex:i]) {
            moveToNumber = i + step;
        }
    }

    // stay in bounds
    if(moveToNumber >= max || moveToNumber < 0) {
        [self.currentField resignFirstResponder];
        return;
    }

    // move on
    UITextField *next = [self.fields objectAtIndex:moveToNumber];
    [next becomeFirstResponder];

}

- (void)prevClicked:(id)sender
{
    [self moveResponderByStep:-1];
}

- (void)nextClicked:(id)sender
{
    [self moveResponderByStep:1];
}