【问题标题】:Best way to use "Next" version of Return button on UITextField to move to next UITextField在 UITextField 上使用“下一个”版本的 Return 按钮移动到下一个 UITextField 的最佳方式
【发布时间】:2009-06-14 05:49:17
【问题描述】:

我使用“返回键”的“下一步”值来获取“下一步”按钮代替“完成”按钮,但(显然)按下它不会自动移动到我视图中的下一个 UITextField。

这样做的正确方法是什么?在一个更大的话题上,在 iPhone SDK 中正确构建表单有哪些技巧?

【问题讨论】:

  • 要将答案标记为正确,只需单击答案旁边的空白复选标记图标...

标签: iphone


【解决方案1】:

使某个对象成为第一个文本字段的委托,并实现- (BOOL)textFieldShouldReturn:(UITextField *)textField 方法;在那里,调用第二个文本字段的-becomeFirstResponder。从中返回YES 将使文本字段执行其返回按钮的默认行为——我认为这通常是发送其操作消息。如果您没有添加任何内容作为该操作的目标,那么您返回的内容并不重要。

【讨论】:

  • ...如果你在最后一个 UITextField 你应该调用 resignFirstResponder 来隐藏键盘。
  • 这是与此处解释的完全不同的方式 (stackoverflow.com/questions/467881/…) 还是两者都可以正常工作?
  • 两者都可以。我的回答使用委托系统,布拉德是目标行动的东西。
  • 与纯文本相比,示例代码几乎总是更好。
  • 感谢您的建议,Engin。
【解决方案2】:

以 Noah 的回答为基础,如果您有很多文本字段并且不想拥有一堆 if,您可以这样做:

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    //[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];

    UIView *view = [self.view viewWithTag:textField.tag + 1];     
    if (!view)         
          [textField resignFirstResponder];     
    else         
          [view becomeFirstResponder];
    return YES;
}

一旦您从任意数字开始标记每个文本字段,只要它们在情节提要或代码中按顺序标记,它应该可以工作。

【讨论】:

  • 很好的解决方案!一项(次要)建议调整 - 测试 viewWithTag == nil:UIView *view = [self.view viewWithTag:textField.tag + 1]; if (!view) [textField resignFirstResponder]; else [view becomeFirstResponder];
【解决方案3】:

对于斯威夫特:

func textFieldShouldReturn(textField: UITextField) -> Bool {
//your collection of textfields
    guard let i = textFields.indexOf(textField) else { return false }
    if i + 1 < textFields.count {
        textFields[i + 1].becomeFirstResponder()
        return true
    }
    textField.resignFirstResponder()
    return true
}

【讨论】:

    【解决方案4】:

    这似乎工作得很好,不需要许多人建议的标签系统。不过,此解决方案有两点需要注意:

    • 所有 UITextFields 必须在同一个 UIView 中(具有相同的 superview)。
    • UITextFields 需要在界面构建器中以正确的顺序排列。

      -(BOOL)textFieldShouldReturn:(UITextField *)textField    {
         /*
         *  1. Loop through the textfield's superview
         *  2. Get the next textfield in the superview  
         *  3. Focus that textfield
         */
      
         UIView *superView = [textField superview];
         BOOL foundCurrent = false;
         for (UITextField *tf in superView.subviews) {
            // Set focus on the next textfield
            if (foundCurrent) {
               [tf becomeFirstResponder];
               return NO;
            }
      
           //Find current textfield
           if ([tf isEqual:textField]) {
               foundCurrent = true;
            }
         }
      
         return YES;
      }    
      

    【讨论】:

      【解决方案5】:

      我不喜欢处理标签,所以这是我的解决方案。在您的ViewController 中创建一个包含所有文本字段的IBOutletCollection,拖动以从上到下依次连接您的文本字段。

      @interface ViewController () <UITextFieldDelegate>
      @property (strong, nonatomic) IBOutletCollection(UITextField) NSArray *allTextFields;
      @end
      

      在 viewDidLoad 中设置您的 textFields 委托。 (或将其设置在情节提要中)。

      for (VVTextField *tf in self.allTextFields) {
          tf.delegate = self;
      }
      

      然后实现 UITextField Delegate

      #pragma mark - UITextField Delegate
      
      - (BOOL)textFieldShouldReturn:(UITextField *)textField {
          NSUInteger currentIndex = [self.allTextFields indexOfObject:textField];
          NSUInteger nextIndex = currentIndex+1;
          if (nextIndex < self.allTextFields.count) {
              [[self.allTextFields objectAtIndex:nextIndex] becomeFirstResponder];
          } else {
              [[self.allTextFields objectAtIndex:currentIndex] resignFirstResponder];
          }
          return YES;
      }
      

      【讨论】:

      • 这可能有效,但不能保证 IBOutletCollection 数组中的对象顺序正确。
      • @JAL 有一个很好的观点。您应该考虑编辑您的答案或以某种方式映射值。这可能会导致意外行为。
      【解决方案6】:

      我也一直在努力解决这个问题……因此,我创建了用于处理多个文本字段的小型库。你可以在github上找到它GNKeyboardAwareScrollView#GNTextFieldsManager。

      您可以使用文本字段数组对其进行初始化:

      NSArray *myTextFields = @[...]; // the order of array matters!
      GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithTextFields:myTextFields];
      

      或者通过指定父视图(并为所有视图设置标签):

      GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithView:self.view];
      

      希望我对某人有用:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多