Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion TextFieldValidator/TextFieldValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ NS_CLASS_AVAILABLE_IOS(6_0) @interface TextFieldValidator : UITextField<UITextFi

@property (nonatomic,assign) BOOL isMandatory; /**< Default is YES*/

@property (nonatomic,retain) IBOutlet UIView *presentInView; /**< Assign view on which you want to show popup and it would be good if you provide controller's view*/
@property (nonatomic,weak) UIView *presentInView; /**< Assign view on which you want to show popup and it would be good if you provide controller's view. If no view is assigned it will automatically assign the superview that containts this TextFieldValidator. */

@property (nonatomic,retain) UIColor *popUpColor; /**< Assign popup background color, you can also assign default popup color from macro "ColorPopUpBg" at the top*/

@property (nonatomic,assign) BOOL validateOnCharacterChanged; /**< Default is YES, Use it whether you want to validate text on character change or not.*/

@property (nonatomic,assign) BOOL validateOnResign; /**< Default is YES, Use it whether you want to validate text on resign or not.*/

/** Used from trimming the text before running the validation. Default is YES */
@property (nonatomic) BOOL trimBeforeValidate;

/**
Use to add regex for validating textfield text, you need to specify all your regex in queue that you want to validate and their messages respectively that will show when any regex validation will fail.
@param strRegx Regex string
Expand Down Expand Up @@ -91,6 +94,9 @@ NS_CLASS_AVAILABLE_IOS(6_0) @interface TextFieldValidator : UITextField<UITextFi
*/
-(BOOL)validate;

/** Checks if the text is valid without showing error message */
- (BOOL)isValid;

/**
Use to dismiss error popup.
*/
Expand Down
100 changes: 65 additions & 35 deletions TextFieldValidator/TextFieldValidator.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,32 @@ @implementation IQPopUp

-(void)drawRect:(CGRect)rect{
const CGFloat *color=CGColorGetComponents(popUpColor.CGColor);

UIGraphicsBeginImageContext(CGSizeMake(30, 20));
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(ctx, color[0], color[1], color[2], 1);
CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), 7.0, [UIColor blackColor].CGColor);
CGPoint points[3] = { CGPointMake(15, 5), CGPointMake(25, 25),
CGPointMake(5,25)};
CGPoint points[3] = { CGPointMake(15, 5), CGPointMake(25, 25),
CGPointMake(5,25)};
CGContextAddLines(ctx, points, 3);
CGContextClosePath(ctx);
CGContextFillPath(ctx);
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGRect imgframe=CGRectMake((showOnRect.origin.x+((showOnRect.size.width-30)/2)), ((showOnRect.size.height/2)+showOnRect.origin.y), 30, 13);

UIImageView *img=[[UIImageView alloc] initWithImage:viewImage highlightedImage:nil];
[self addSubview:img];
img.translatesAutoresizingMaskIntoConstraints=NO;
NSDictionary *dict=NSDictionaryOfVariableBindings(img);
[img.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-%f-[img(%f)]",imgframe.origin.x,imgframe.size.width] options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:dict]];
[img.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|-%f-[img(%f)]",imgframe.origin.y,imgframe.size.height] options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:dict]];

UIFont *font=[UIFont fontWithName:FontName size:FontSize];
CGSize size=[self.strMsg boundingRectWithSize:CGSizeMake(fieldFrame.size.width-(PaddingInErrorPopUp*2), 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size;
size=CGSizeMake(ceilf(size.width), ceilf(size.height));

UIView *view=[[UIView alloc] initWithFrame:CGRectZero];
[self insertSubview:view belowSubview:img];
view.backgroundColor=self.popUpColor;
Expand All @@ -69,7 +69,7 @@ -(void)drawRect:(CGRect)rect{
lbl.text=self.strMsg;
lbl.textColor=ColorFont;
[view addSubview:lbl];

lbl.translatesAutoresizingMaskIntoConstraints=NO;
dict=NSDictionaryOfVariableBindings(lbl);
[lbl.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-%f-[lbl(%f)]",(float)PaddingInErrorPopUp,size.width] options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:dict]];
Expand Down Expand Up @@ -164,13 +164,13 @@ -(void)tapOnError;
@end

@implementation TextFieldValidator
@synthesize presentInView,validateOnCharacterChanged,popUpColor,isMandatory,validateOnResign;
@synthesize validateOnCharacterChanged,popUpColor,isMandatory,validateOnResign;

#pragma mark - Default Methods of UIView
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {

}
return self;
}
Expand All @@ -181,6 +181,7 @@ -(id)initWithCoder:(NSCoder *)aDecoder{
validateOnCharacterChanged=YES;
isMandatory=YES;
validateOnResign=YES;
_trimBeforeValidate = YES;
popUpColor=ColorPopUpBg;
strLengthValidationMsg=[MsgValidateLength copy];
supportObj=[[TextFieldValidatorSupport alloc] init];
Expand All @@ -206,6 +207,14 @@ -(void)setValidateOnResign:(BOOL)validate{
validateOnResign=validate;
}

- (UIView *)presentInView
{
if (_presentInView == nil) {
_presentInView = [self superview];
}
return _presentInView;
}

#pragma mark - Public methods
-(void)addRegx:(NSString *)strRegx withMsg:(NSString *)msg{
NSDictionary *dic=[[NSDictionary alloc] initWithObjectsAndKeys:strRegx,@"regx",msg,@"msg", nil];
Expand All @@ -222,27 +231,12 @@ -(void)addConfirmValidationTo:(TextFieldValidator *)txtConfirm withMsg:(NSString
}

-(BOOL)validate{
if(isMandatory){
if([self.text length]==0){
[self showErrorIconForMsg:strLengthValidationMsg];
return NO;
}
}
for (int i=0; i<[arrRegx count]; i++) {
NSDictionary *dic=[arrRegx objectAtIndex:i];
if([dic objectForKey:@"confirm"]){
TextFieldValidator *txtConfirm=[dic objectForKey:@"confirm"];
if(![txtConfirm.text isEqualToString:self.text]){
[self showErrorIconForMsg:[dic objectForKey:@"msg"]];
return NO;
}
}else if(![[dic objectForKey:@"regx"] isEqualToString:@""] && [self.text length]!=0 && ![self validateString:self.text withRegex:[dic objectForKey:@"regx"]]){
[self showErrorIconForMsg:[dic objectForKey:@"msg"]];
return NO;
}
}
self.rightView=nil;
return YES;
return [self validateShowingErrorMessage:YES];
}

- (BOOL)isValid
{
return [self validateShowingErrorMessage:NO];
}

-(void)dismissPopup{
Expand All @@ -264,6 +258,42 @@ - (BOOL)validateString:(NSString*)stringToSearch withRegex:(NSString*)regexStrin
return [regex evaluateWithObject:stringToSearch];
}

- (BOOL)validateShowingErrorMessage:(BOOL)showErrorMessage
{
if (self.trimBeforeValidate) {
self.text = [self.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if(isMandatory){
if([self.text length]==0){
if (showErrorMessage) {
[self showErrorIconForMsg:strLengthValidationMsg];
}
return NO;
}
}
for (int i=0; i<[arrRegx count]; i++) {
NSDictionary *dic=[arrRegx objectAtIndex:i];
if([dic objectForKey:@"confirm"]){
TextFieldValidator *txtConfirm=[dic objectForKey:@"confirm"];
if(![txtConfirm.text isEqualToString:self.text]){
if (showErrorMessage) {
[self showErrorIconForMsg:[dic objectForKey:@"msg"]];
}
return NO;
}
}else if(![[dic objectForKey:@"regx"] isEqualToString:@""] && [self.text length]!=0 && ![self validateString:self.text withRegex:[dic objectForKey:@"regx"]]){
if (showErrorMessage) {
[self showErrorIconForMsg:[dic objectForKey:@"msg"]];
}
return NO;
}
}
if (showErrorMessage) {
self.rightView=nil;
}
return YES;
}

-(void)showErrorIconForMsg:(NSString *)msg{
UIButton *btnError=[[UIButton alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[btnError addTarget:self action:@selector(tapOnError) forControlEvents:UIControlEventTouchUpInside];
Expand All @@ -277,11 +307,11 @@ -(void)showErrorWithMsg:(NSString *)msg{
popUp=[[IQPopUp alloc] initWithFrame:CGRectZero];
popUp.strMsg=msg;
popUp.popUpColor=popUpColor;
popUp.showOnRect=[self convertRect:self.rightView.frame toView:presentInView];
popUp.fieldFrame=[self.superview convertRect:self.frame toView:presentInView];
popUp.showOnRect=[self convertRect:self.rightView.frame toView:self.presentInView];
popUp.fieldFrame=[self.superview convertRect:self.frame toView:self.presentInView];
popUp.backgroundColor=[UIColor clearColor];
[presentInView addSubview:popUp];
[self.presentInView addSubview:popUp];

popUp.translatesAutoresizingMaskIntoConstraints=NO;
NSDictionary *dict=NSDictionaryOfVariableBindings(popUp);
[popUp.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[popUp]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:dict]];
Expand Down