UITextField shouldChangeCharactersinRange as external function

76 Views Asked by At

I want to validate UITextField input for multiple view controllers. The following works:

validate.h

#import <UIKit/UIKit.h>

@interface validate : UITextField <UITextFieldDelegate>
@end

validate.m

#import "validate.h"

@implementation validate

viewController.h

#import <UIKit/UIKit.h>
#include "limiteTextField.h"

@interface ViewController : UIViewController <UITextFieldDelegate>
@property (strong, nonatomic) IBOutlet limiteTextField *myTextField;
@end

viewController.m

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController  

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
 //my code for validating 
}

- (void)viewDidLoad {
    [super viewDidLoad];
    _myTextField.delegate=self;

I want to be able to use the shouldChangeCharactersInRange as an external function so don't have to rewrite all its code for each view controller.

2

There are 2 best solutions below

0
On BEST ANSWER

One approach is to create some kind of validator class with a singleton and assigning it as the textfields delegate:

TextFieldValidator.h

#import <UIKit/UIKit.h>

@interface TextFieldValidator : NSObject <UITextFieldDelegate>

+ (instancetype)sharedValidator;

@end

TextFieldValidator.m

#import "TextFieldValidator.h"

@implementation TextFieldValidator

+ (instancetype)sharedValidator {
    static TextFieldValidator *sharedValidator = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedValidator = [[self alloc] init];
    });
    return sharedValidator;
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSCharacterSet *allowedCharacters = [NSCharacterSet decimalDigitCharacterSet];
    return [[textField.text stringByReplacingCharactersInRange:range withString:string] rangeOfCharacterFromSet:allowedCharacters.invertedSet].location == NSNotFound;
}

@end

SomeViewController.m

// [...]

self.textField.delegate = [TextFieldValidator sharedValidator];

// [...]
2
On

I want to be able to use the shouldChangeCharactersInRange as an external function so don't have to rewrite all its code for each view controller.

Then do so. This is a delegate method. Anything can be the delegate. You are the one who is setting the text field's delegate to be different view controllers! If you don't want to do that, then don't. Have some single persistent object, or at least multiple instance of the same class, and make that the delegate of the text field. Now all text fields can use this same delegate which has just one implementation of shouldChangeCharactersInRange.