Reputation: 924
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
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
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
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
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