iOS 5:在TextField之间跳转时出现奇怪的行为

时间:2012-01-26 15:37:29

标签: uitableview ios5 uitextfield

在我的应用中,我有一个非常大的表格可以填写。表单本身是使用表格视图和静态单元格模式。每个单元格包含标签和文本字段。我想在键盘上方添加一个工具栏,以便在文本字段之间导航。我做到了,但它表现得非常奇怪(至少我认为)。

跳转到下一个文本字段时没有问题,只有在可见时跳转到上一个文本字段才有可能。如果它不可见,旧的文本字段保持第一响应者,但是当我滚动我的表视图并且预期的文本字段变得可见时,它成为第一个响应者(我没有点击它!)。那么这当然不是我想要的行为。

我的问题是:这种行为是否正常?你能以某种方式绕过它吗?

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

我使用静态单元格设置了分组表格视图。每个都包含一个标签和textfield。我为每个文本字段创建了出口以获取对它们的访问权限。在我的viewDidLoad方法中,我创建工具栏及其按钮,将文本字段存储在一个数组中,并将控制器设置为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;
    }
}

文本字段委托方法存储活动文本字段的引用,并防止插入换行符。

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    textField.inputAccessoryView = self.keyboardToolbar;
    return YES;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    // set the current active textfield
    self.currentField = textField;

    // scroll this textfield to top
    UITableViewCell *cell = (UITableViewCell *)textField.superview.superview;
    [self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    self.currentField = nil; 
    return NO;
}

最后,工具栏按钮的选择器和获取下一个文本字段的逻辑。

- (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];
}

谢谢!

1 个答案:

答案 0 :(得分:0)

首先尝试检查该行是否可见。如果不是,则将行滚动到可见。然后将文本字段设置为第一响应者。