如何在多个textfield中切换

Approach 1:

-(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.}

Add some more code, and the assumptions can be ignored as well.

这个方法的缺点:

This approach is fragile. You should never use magic numbers to determine anything. I realize that it's a quick and dirty fix, but a more robust solution can be had that will use less code. See my answer below. My answer will use n*4 less lines of code (n = the number of times you need to use textFieldShouldReturn in your view controllers), is more robust, and is very easy to implement to boot.


Approach 2:

There is a much more elegant solution which blew me away the first time I saw it. Benefits:

  • Closer to OSX textfield implementation where a textfield knows where the focus should go next

  • Does not rely on setting or using tags -- which are, IMO fragile for this use case

  • Can be extended to work with both UITextField and UITextView controls -- or any keyboard entry UI control

  • Doesn't clutter your view controller with boilerplate UITextField delegate code

  • Integrates nicely with IB and can be configured through the familiar option-drag-drop to connect outlets.

Create a UITextField subclass which has an IBOutlet property called nextField. Here's the header:

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

And here's the implementation:

@implementation SOTextField
@synthesize nextField;
@end

In your view controller, you'll create the -textFieldShouldReturn: delegate method:

- (BOOL) textFieldShouldReturn:(UITextField *) textField {

    BOOL didResign = [textField resignFirstResponder];
    if (!didResign) return NO;

    if ([textField isKindOfClass:[SOTextField class]])
        dispatch_async(dispatch_get_current_queue(), 
           ^ { [[(SOTextField *)textField nextField] becomeFirstResponder]; });

    return YES;}

In IB, change your UITextFields to use the SOTextField class. Next, also in IB, set the delegate for each of the 'SOTextFields'to 'File's Owner' (which is right where you put the code for the delegate method - textFieldShouldReturn). The beauty of this design is that now you can simply right-click on any textField and assign the nextField outlet to the next SOTextField object you want to be the next responder.

如何在多个textfield中切换

Moreover, you can do cool things like loop the textFields so that after the last one looses focus, the first one will receive focus again.

This can easily be extended to automatically assign the returnKeyType of the SOTextField to a UIReturnKeyNext if there is a nextField assigned -- one less thing manually configure.


不得不说,这2个答案下面另外2个更好,subclass那个,和textfield数组那个。

你可能感兴趣的:(ios,textfield)