user2503846
user2503846

Reputation: 924

Subclassing UITextField

I'd like to create a text field which uses the number pad and accepts only numbers, even when pasted. Currently, I have a header as such:

#import <UIKit/UIKit.h>

@interface DRPNumberTextField : UITextField <UITextFieldDelegate>

@end

and an implementation:

#import "DRPNumberTextField.h"

@implementation DRPNumberTextField

- (id) initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self)
  {
    self.delegate = self;
    [self setKeyboardType:UIKeyboardTypeNumberPad];
  }
  return self;
}

- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
  if ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)
  {
    return NO;
  }
  return YES;
}

/*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {
 // Drawing code
 }
 */

@end

I've set the text fields to use this class in the storyboard. However, my desired functionality does not occur. Moreover, as determined by debugging, initWithFrame: is never called. Any ideas? As more context, these text fields are embedded inside table cells of a table view of a table view controller. Of these, I provide a custom implementation of the table view controller here:

@interface DRPImplementSettingsViewController ()

@end

@implementation DRPImplementSettingsViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end

Thus it really has no implemented functionality beyond the stock. Its header is the obvious one.

EDIT: As some have pointed out, I don't need to subclass the text field to implement delegate functionality. I can put that elsewhere. But my question is this: why doesn't what I've presented here work? I can't find my mistake.

Upvotes: 3

Views: 5055

Answers (4)

user2893025
user2893025

Reputation:

You can try with this also,

Its also works

DRPNumberTextField.m

#import "DRPNumberTextField.h"

@implementation DRPNumberTextField
- (void)awakeFromNib
{
    [super awakeFromNib];

    self.delegate = self;
    [self setKeyboardType:UIKeyboardTypeNumberPad];

}

- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)
    {
        return NO;
    }
    return YES;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

@end

Upvotes: 1

chancyWu
chancyWu

Reputation: 14383

You need also override - (id)initWithCoder:(NSCoder *)decoder in your DRPNumberTextField. if you are using the custom UITextField in XIB or storyboard, initWithFrame: will not be called, initWithCoder: is called instead.

Upvotes: 8

Toseef Khilji
Toseef Khilji

Reputation: 17409

Here is an alternative to subclassing, rather subclassing you can use delegate method of textfield for that

check this,

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
#define NUMBERS @"0123456789"
#define NUMBERSPERIOD @"0123456789-"
    NSCharacterSet *cs;
    NSString *filtered;
        // Period is in use
    if (textField.tag==8)
    {
        cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet];
        filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
        return [string isEqualToString:filtered];

    }
    return YES;

}

Set your textfield tag appropriate . It will also want past other character.

Upvotes: 0

Nathan Day
Nathan Day

Reputation: 6037

You don't need to subclass to do this, you can just implement theUITextFieldDelegate method textField:shouldChangeCharactersInRange:replacementString:. Every time the method is called check that the replacementString only contains characters you want to allow and return YES or NO depending on whether it does.

Upvotes: 0

Related Questions