Text Field Should Return, is this correct for ios7?

可紊 提交于 2019-12-08 07:44:51

问题


I have searched and seen a lot of answers about textFieldShouldReturn method. Half of them are outdated, some work in different cases, some are not explained thoroughly. I am not sure what is the most optimal way to do this task, it works but I think there might be an easier way to do it.

Heres my code so far:

On the header file:

@interface ClassName : SomeUIViewController <UITextFieldDelegate>

In the implementation file:

@interface ClassName()

@property (weak, nonatomic) IBOutlet UITextField *firstOne;
@property (weak, nonatomic) IBOutlet UITextField *secondOne;
@property (weak, nonatomic) IBOutlet UITextField *thirdOne;
@property (weak, nonatomic) IBOutlet UITextField *fourthOne;
@property (weak, nonatomic) IBOutlet UITextField *fifthOne;

@end

-(void)viewDidLoad{
    self.firstOne.delegate = self;
    self.secondOne.delegate = self;
    self.thirdOne.delegate = self;
    self.fourthOne.delegate = self;
    self.fifthOne.delegate = self;
}

-(BOOL)textFieldShouldReturn:(UITextField*)textField;
{
    if (textField == self.firstOne) {
        [textField resignFirstResponder];
        [self.secondOne becomeFirstResponder];
    } else if (textField == self.secondOne) {
        [textField resignFirstResponder];
        [self.thirdOne becomeFirstResponder];
    } else if (textField == self.thirdOne) {
        [textField resignFirstResponder];
        [self.fourthOne becomeFirstResponder];
    } else if (textField == self.fourthOne) {
        [textField resignFirstResponder];
        [self.fifthOne becomeFirstResponder];
    } else if (textField == self.fifthOne) {
        [textField resignFirstResponder];
    }

    return NO; 
}

So is this correct or are there better ways to do this task?


回答1:


In general your code is fine.

If you are using IB (Interface Builder) you can set the delegate there instead of in code.

Example: control drag from the UITextField to the ViewController and select "delegate".

The resignFirstResponder could be factored to ibe occurrence
Refactored code:

-(BOOL)textFieldShouldReturn:(UITextField*)textField;
{
    [textField resignFirstResponder];

    if (textField == self.firstOne) {
        [self.secondOne becomeFirstResponder];
    } else if (textField == self.secondOne) {
        [self.thirdOne becomeFirstResponder];
    } else if (textField == self.thirdOne) {
        [self.fourthOne becomeFirstResponder];
    } else if (textField == self.fourthOne) {
        [self.fifthOne becomeFirstResponder];
    }

    return NO; 
}



回答2:


I propose you an other way to do this. You can create a new class, extending UITextField class with a category, and add your own property to navigate between UIControls.

// Class name UITextField+Navigation.h
@interface UITextField (Navigation)

@property (weak, nonatomic) IBOutlet id nextUIControl;

@end

The IBOutlet is for if you want to use the property with the storyboard, you can omit it if you want.

// UITextField+Navigation.m
#import "UITextField+Navigation.h"
#import <objc/runtime.h>

static char defaultHashKey;

@implementation UITextField (Navigation)

- (id)nextUIControl
{
    return objc_getAssociatedObject(self, &defaultHashKey);
}

- (void)setNextUIControl:(id)nextUIControl
{
    objc_setAssociatedObject(self, &defaultHashKey, nextUIControl, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

In your class, import the extended UITextField+Navigation.h class so you can access the property you have created. In the viewDidLoad method you just assign the value of the next UITextField

#import "UITextField+Navigation.h"

@interface ClassName()

@property (weak, nonatomic) IBOutlet UITextField *firstOne;
@property (weak, nonatomic) IBOutlet UITextField *secondOne;
@property (weak, nonatomic) IBOutlet UITextField *thirdOne;
@property (weak, nonatomic) IBOutlet UITextField *fourthOne;
@property (weak, nonatomic) IBOutlet UITextField *fifthOne;

@end
- (void)viewDidLoad
{
    self.firstOne.nextUIControl = self.secondOne;
    self.secondOne.nextUIControl = self.thirdOne;
    etc...
}


Or if you are using Storyboards, you can link the controllers to the nextUIControl property.

And in the textFieldShouldReturn:
-(BOOL)textFieldShouldReturn:(UITextField*)textField;
{
    [textField.nextUIControl  becomeFirstResponder];
    return NO; 
}



回答3:


My 50 cents. I use the next approach. UIKit objects (UIView, UITextField and other) have a rewritable property called "tag". It's a property for developer use.

typedef NS_ENUM (NSInteger, SSSActionType) {
    TextFieldTag1= 100,
    TextFieldTag2= 110,
    TextFieldTag3= 120
};

- (void)customizeFields {
    textField1.tag = TextFieldTag1;
    textField1.delegate = self;

    // setting tags for all fields
}

In delegate methods compare integer tags instead of instance objects:

-(BOOL)textFieldShouldReturn:(UITextField*)textField {
    [textField resignFirstResponder];

    switch (textField.tag) {
        case TextFieldTag1:
          // do stuff
          break;

        case TextFieldTag2:
          break;

        case TextFieldTag3:
          break;

        default:
          break;
    }

    return NO; 
}

Looks like the first approach but I prefer explicit tags name and clear code




回答4:


as well as above good answers . you can still findout good library who manage all the stuffs of textfield . like when you are using textfields in tableview , textfields in collectionview . https://github.com/michaeltyson/TPKeyboardAvoiding. by using this library you can easily make login or sign up forms for app




回答5:


My solution in Swift:
Create a dictionary mapping between a TextField and the next one.

// to find the next text field
private lazy var textFields: [UITextField: UITextField] =
     [self.firstTF: self.secondTF,
      self.secondTF: self.thirdTF]

func textFieldShouldReturn(textField: UITextField) -> Bool {
    textFields[textField]?.becomeFirstResponder()
    return true
}



回答6:


I put every textfield a tag number consecutive. like 0,1,2,3..n then the usage is:

func textFieldShouldReturn(textField: UITextField) -> Bool {

    let tag = textField.tag

    if (tag < n)
    {
        let textfieldNew = theView.viewWithTag(tag + 1) as! UITextField
        textfieldNew.becomeFirstResponder()
    }
    else
    {
        textField.resignFirstResponder()

    }
    return true
}


来源:https://stackoverflow.com/questions/21687778/text-field-should-return-is-this-correct-for-ios7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!