如何浏览文本框(下一个/完成按钮)

如何通过iPhone键盘上的“下一步”按钮浏览所有文本字段?

最后一个文本字段应该关闭键盘。

我已经设置了IB按钮(Next / Done),但现在我卡住了。

我实现了textFieldShouldReturn操作,但现在Next和Done按钮关闭了键盘。


在Cocoa for Mac OS X中,您有下一个响应者链,您可以在其中询问文本字段接下来应该关注哪些控件。 这是使文本字段之间的tab键工作的原因。 但是由于iOS设备没有键盘,只能触摸,这个概念在转换到Cocoa Touch之后还没有生存下来。

无论如何,这可以轻松完成,有两个假设:

  • 所有“可放大”的UITextField都在同一个父视图中。
  • 他们的“tab-order”由标签属性定义。
  • 假设这可以覆盖textFieldShouldReturn:如下所示:

    -(BOOL)textFieldShouldReturn:(UITextField*)textField
    {
      NSInteger nextTag = textField.tag + 1;
      // Try to find next responder
      UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
      if (nextResponder) {
        // Found next responder, so set it.
        [nextResponder becomeFirstResponder];
      } else {
        // Not found, so remove keyboard.
        [textField resignFirstResponder];
      }
      return NO; // We do not want UITextField to insert line-breaks.
    }
    

    再添加一些代码,这些假设也可以被忽略。

    Swift 4.0

     func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        let nextTag = textField.tag + 1
        // Try to find next responder
        let nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder!
    
        if nextResponder != nil {
            // Found next responder, so set it
            nextResponder?.becomeFirstResponder()
        } else {
            // Not found, so remove keyboard
            textField.resignFirstResponder()
        }
    
        return false
    }
    

    如果文本字段的超级视图将是一个UITableViewCell,那么下一个响应者将是

    let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!
    

    当我第一次看到它时,有一种更加优雅的解决方案将我吹走。 优点:

  • 更接近OSX文本字段实现,其中文本字段知道焦点应该放在哪里
  • 不依赖于设置或使用标签 - 对于这种用例,IMO是脆弱的
  • 可以扩展到与UITextFieldUITextView控件一起工作 - 或任何键盘输入UI控件
  • 不要使用样板UITextField委托代码来混乱视图控制器
  • 与IB很好地集成,并且可以通过熟悉的选项 - 拖放来连接插座进行配置。
  • 创建一个名为nextField的具有IBOutlet属性的UITextField子类。 这是标题:

    @interface SOTextField : UITextField
    
    @property (weak, nonatomic) IBOutlet UITextField *nextField; 
    
    @end
    

    这是实现:

    @implementation SOTextField
    
    @end
    

    在您的视图控制器中,您将创建-textFieldShouldReturn:委托方法:

    - (BOOL)textFieldShouldReturn:(UITextField *)textField {
        if ([textField isKindOfClass:[SOTextField class]]) {
            UITextField *nextField = [(SOTextField *)textField nextField];
    
            if (nextField) {
                dispatch_async(dispatch_get_current_queue(), ^{
                    [nextField becomeFirstResponder];
                });
            }
            else {
                [textField resignFirstResponder];
            }
        }
    
        return YES;
    }
    

    在IB中,将您的UITextFields更改为使用SOTextField类。 接下来,在IB中,将每个“SOTextFields”的委托设置为“文件所有者”(这就是您为委托方法放置代码的位置 - textFieldShouldReturn)。 这种设计的美妙之处在于,现在只需右键单击任何textField并将nextField插座指定给您希望成为下一个响应者的下一个SOTextField对象。

    此外,你可以做一些很酷的事情,像循环textFields,以便在最后一个失去焦点后,第一个焦点会再次获得焦点。

    这可以很容易地扩展到自动分配returnKeyType的的SOTextFieldUIReturnKeyNext如果有nextField分配-少了一个东西手动配置。


    这是我解决这个问题的方法。

    为了解决这个问题(因为我讨厌依靠标签来做东西),我决定向UITextField对象添加一个自定义属性。 换句话说,我在UITextField上创建了一个类,如下所示:

    的UITextField + Extended.h

    @interface UITextField (Extended)
    
    @property(retain, nonatomic)UITextField* nextTextField;
    
    @end
    

    的UITextField + Extended.m

    #import "UITextField+Extended.h"
    #import <objc/runtime.h>
    
    static char defaultHashKey;
    
    @implementation UITextField (Extended)
    
    - (UITextField*) nextTextField { 
        return objc_getAssociatedObject(self, &defaultHashKey); 
    }
    
    - (void) setNextTextField:(UITextField *)nextTextField{
        objc_setAssociatedObject(self, &defaultHashKey, nextTextField, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
    }
    
    @end
    

    现在,我使用它的方式如下:

    UITextField *textField1 = ...init your textfield
    UITextField *textField2 = ...init your textfield
    UITextField *textField3 = ...init your textfield
    
    textField1.nextTextField = textField2;
    textField2.nextTextField = textField3;
    textField3.nextTextField = nil;
    

    并执行textFieldShouldReturn方法:

    - (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    
        UITextField *next = theTextField.nextTextField;
        if (next) {
            [next becomeFirstResponder];
        } else {
            [theTextField resignFirstResponder];
        }
    
        return NO; 
    }
    

    我现在有一个UITextField的链表,每个链表都知道谁在下一行。

    希望它会有所帮助。

    链接地址: http://www.djcxy.com/p/73497.html

    上一篇: How to navigate through textfields (Next / Done Buttons)

    下一篇: Change placeholder text color