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

Posted

技术标签:

【中文标题】iOS 5:在 TextField 之间跳转时出现奇怪的行为【英文标题】:iOS 5: Strange behavior when jumping in between TextFields 【发布时间】:2012-01-26 15:37:28 【问题描述】:

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

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

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

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

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

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

谢谢!

【问题讨论】:

在更改第一响应者之前,您是否尝试滚动表格视图以使上一个单元格可见。 感谢@dasdom 和抢劫。我应该提到我试过了。问题是如果单元格不可见, indexPathForCell 将返回 null 。在我的应用程序中,并非每一行都包含一个文本字段,所以我必须在其他地方跟踪它们的位置。它当然有效,但在我看来不是一个理想的解决方案。 【参考方案1】:

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

【讨论】:

以上是关于iOS 5:在 TextField 之间跳转时出现奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

在一个组件中使用 formik-material-ui TextField 和 material-ui TextField 时出现“警告:Prop `className` 不匹配...”

文本不为空时出现Flutter textfield clear按钮

IOS AutoLayout在横向和纵向之间切换时出现约束异常

尝试在 NavigationController 中推送多个 UIViewController 时出现 iOS8 问题

尝试在 iPhone 5 上运行 iOS 8 应用程序时出现 dyld 错误

(编辑:iOS Simulator 5.x 错误)在 iOS 中使用 AudioQueue 进行声音播放时出现 EXC_BAD_ACCESS