Internship/2020 year-end summer internship
Setting an overlay for textfield (on the left)
hajinny
2021. 2. 12. 11:20
This functionality is actually super easy to implement, if you are familiar with how UITextFieldDelegate works in objective C (an article was written about this 2 articles ago).
I had to find a way to do something like this:
This is done like this:
//
// ViewController.m
// Tutorial
//
// Created by Developer on 9/02/21.
// Copyright © 2021 Developer. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
- (IBAction)hello:(id)sender;
@property (weak, nonatomic) IBOutlet UITextField *creditTextField;
@end
@implementation ViewController
static NSString *const visaRegex = @"^4[0-9]{6,}$";
static NSString *const mastercardRegex = @"^5[1-5][0-9]{5,}|222[1-9][0-9]{3,}|22[3-9][0-9]{4,}|2[3-6][0-9]{5,}|27[01][0-9]{4,}|2720[0-9]{3,}$";
static NSString *const americanexpressRegex = @"^3[47][0-9]{5,}$";
- (IBAction)hello:(id)sender{
NSLog(@"hi!");
}
- (void)setTextFieldImage: (UITextField*)textField :(NSString *)iconName
{
UIImage *image = [UIImage imageNamed:iconName];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(24, 24), NO, 1.0);
[image drawInRect:CGRectMake(0, 0, 24, 24)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *leftImageView = [[UIImageView alloc] initWithImage:image];
leftImageView.contentMode = UIViewContentModeLeft;
leftImageView.frame = CGRectMake(0.0f, 0.0f, leftImageView.image.size.width + 10.0f, leftImageView.image.size.height);
textField.leftViewMode = UITextFieldViewModeAlways;
textField.leftView = leftImageView;
}
- (void)viewDidLoad {
[self setTextFieldImage:_creditTextField :@"card"];
[super viewDidLoad];
// Do any additional setup after loading the view.
self.creditTextField.delegate = self;
}
- (BOOL)checkRegex:(NSString *)pattern against:(NSString *)raw{
return [raw rangeOfString:pattern options:NSRegularExpressionSearch].location != NSNotFound;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *filter = @"#### #### #### ####";
if(!filter) return YES; // No filter provided, allow anything
NSLog(@"%@", NSStringFromRange(range));
NSLog(@"%@", string);
NSString *changedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if(range.length == 1 && // Only do for single deletes
[[textField.text substringWithRange:range] rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"0123456789"]].location == NSNotFound)
{
// Something was deleted. Delete past the previous number
NSInteger location = changedString.length-1;
if(location >= 0)
{
for(; location > 0; location--)
{
if(isdigit([changedString characterAtIndex:location]))
{
break;
}
}
changedString = [changedString substringToIndex:location];
}
}
textField.text = filteredCreditCardStringFromStringWithFilter(changedString, filter);
NSString *rawCreditCard = [textField.text stringByReplacingOccurrencesOfString:@" " withString:@""];
if([self checkRegex:visaRegex against:rawCreditCard]){
[self setTextFieldImage:_creditTextField :@"visa"];
}else if([self checkRegex:mastercardRegex against:rawCreditCard]){
[self setTextFieldImage:_creditTextField :@"mastercard"];
}else if([self checkRegex:americanexpressRegex against:rawCreditCard]){
[self setTextFieldImage:_creditTextField :@"americanexpress"];
}else{
[self setTextFieldImage:_creditTextField :@"card"];
}
return NO;
}
NSString *filteredCreditCardStringFromStringWithFilter(NSString *string, NSString *filter)
{
NSUInteger onOriginal = 0, onFilter = 0, onOutput = 0;
char outputString[([filter length])];
BOOL done = NO;
while(onFilter < [filter length] && !done)
{
char filterChar = [filter characterAtIndex:onFilter];
char originalChar = onOriginal >= string.length ? '\0' : [string characterAtIndex:onOriginal];
switch (filterChar) {
case '#':
if(originalChar=='\0')
{
// We have no more input numbers for the filter. We're done.
done = YES;
break;
}
if(isdigit(originalChar))
{
outputString[onOutput] = originalChar;
onOriginal++;
onFilter++;
onOutput++;
}
else
{
onOriginal++;
}
break;
default:
// Any other character will automatically be inserted for the user as they type (spaces, - etc..) or deleted as they delete if there are more numbers to come.
outputString[onOutput] = filterChar;
onOutput++;
onFilter++;
if(originalChar == filterChar)
onOriginal++;
break;
}
}
outputString[onOutput] = '\0'; // Cap the output string
return [NSString stringWithUTF8String:outputString];
}
@end