Delete key event in iPhone - iphone

I created UITextField. I need only 4 numeric characters only allowed that textfield.
I used the following code and get result.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber* candidateNumber;
NSString* candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];
range = NSMakeRange(0, [candidateString length]);
[numberFormatter getObjectValue:&candidateNumber forString:candidateString range:&range error:nil];
NSUInteger newLength = [passwordfield.text length];
if(newLength>=4)
{
[passwordfield setText:[passwordfield.text substringToIndex:3]];
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"Alert"];
[alert setMessage:#"Four Characters only allowed.."];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Ok"];
[alert show];
}
if (([candidateString length] > 0) && (candidateNumber == nil || range.length < [candidateString length]))
{
return NO;
}
else
{
return YES;
}
}
But my problem is when I press delete key, last two characters are deleting
and same time alertview also display.
How to solve this issue?

You're making this more complex than it needs to be. When a user taps the backspace key, the incoming string is a blank string; [NSString string]. Here's a working solution:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
if (![numberFormatter numberFromString:string] && ![string isEqualToString:[NSString string]]) {
return NO;
}
if (textField.text.length + string.length > 4) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Four Characters only allowed..."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
return NO;
} else {
return YES;
}
}

Related

Textfield Input Validation in iPhone SDK

I have to put validation on a UITextField for user input.
The user must input into the textfield a value
i.e. 70-80 or 85 mean num-num or num
Right now, I just allow to user to input only digits& - but drawback is that user can also input - number of times.
// My code is as follow
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789-"] invertedSet];
if (([txtMarks.text rangeOfCharacterFromSet:set].location != NSNotFound )||[txtMarks.text isEqualToString:#""] ) {
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#"Invalid Input" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}
Simply Try this,
int times = [[txtMarks.text componentsSeparatedByString:#"-"] count]-1;
if(times>1)
{
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#"'-' used more than one" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}
EDIT 1
Using NSPredicate we can do it. Try this,
NSString *regex = #"[0-9]+(-[0-9]+)?";
NSPredicate *testRegex = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
if([testRegex evaluateWithObject:textField.text])
NSLog(#"Match");
else
NSLog(#"Do not match");
Hope that can help.
Try this first find whether your string contains -
Here subtring is -
if ([txtMarks.text hasPrefix:#"-"]||[txtMarks.text hasSuffix:#"-"])
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"sorry " message:#"invalid inoput as it has - at start or end" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
else
{
NSRange textRange;
textRange =[string rangeOfString:substring];
if(textRange.location == NSNotFound)
{
//Does not contain the substring
NSlog(#" string contains only num")
}
else
{
int times = [[txtMarks.text componentsSeparatedByString:#"-"] count];
if(times==2)
{
Nslog(#"num-num input")
}
else
{
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#"'-' used more than one" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}
}
}
Try it using the following regular expression, It restricts user to enter more than one -.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *expression = #"^([0-9]{1,}+)?(\\-([0-9]{1,})?)?$";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionCaseInsensitive
error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString
options:0
range:NSMakeRange(0, [newString length])];
if (numberOfMatches == 0)
{
return NO;
}
return YES;
}

In-App purchases not working on iPhone?

This is the code:
-(IBAction)purchase5010:(id)sender{
productUserRequests = 0;
SKPayment *payment = [SKPayment paymentWithProductIdentifier:#"com.mobice.wtm.5010"];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
SKProduct *validProduct = nil;
int count = [response.products count];
if (count > 0) {
validProduct = [response.products objectAtIndex:productUserRequests];
}else if(!validProduct){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"No products available at this time."
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[self dismissModalViewControllerAnimated:YES];
}
}
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if (count > 0) {
validProduct = [response.products objectAtIndex:productUserRequests];
}else if(!validProduct){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"No products available at this time."
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[self dismissModalViewControllerAnimated:YES];
}
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
break;
case SKPaymentTransactionStatePurchased:
if (productUserRequests == 0) {
NSString *hints = [[NSString alloc]initWithContentsOfFile:[self pathOfFile:#"Hints"]];
int hintValue = [hints intValue];
hintValue+=50;
[hints release];
hints = [[NSString alloc]initWithFormat:#"%i", hintValue];
[hints writeToFile:[self pathOfFile:#"Hints"] atomically:YES];
NSString *reveals = [[NSString alloc]initWithContentsOfFile:[self pathOfFile:#"Reveals"]];
int revealValue = [reveals intValue];
revealValue+=50;
[reveals release];
reveals = [[NSString alloc]initWithFormat:#"%i", revealValue];
[reveals writeToFile:[self pathOfFile:#"Reveals"] atomically:YES];
}else if(productUserRequests == 1){
NSString *hints = [[NSString alloc]initWithContentsOfFile:[self pathOfFile:#"Hints"]];
int hintValue = [hints intValue];
hintValue+=150;
[hints release];
hints = [[NSString alloc]initWithFormat:#"%i", hintValue];
[hints writeToFile:[self pathOfFile:#"Hints"] atomically:YES];
NSString *reveals = [[NSString alloc]initWithContentsOfFile:[self pathOfFile:#"Reveals"]];
int revealValue = [reveals intValue];
revealValue+=20;
[reveals release];
reveals = [[NSString alloc]initWithFormat:#"%i", revealValue];
[reveals writeToFile:[self pathOfFile:#"Reveals"] atomically:YES];
}
case SKPaymentTransactionStateFailed:
if (transaction.error.code != SKErrorPaymentCancelled) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"In-app purchase failed. No money was charged."
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
break;
}
}
}
Now, whenever I attempt to purchase the item, it says "No products available at this time.", and also "In-app purchase failed. No money was charged."
I want to know, is there something wrong with the code above? Or is it more likely an itunes connect issue?
Instead of the full bundle id for the request: #"com.mobice.wtm.5010", go ahead and feed it just a #"5010".
For example I have a product com.example.somerandomapp.track01 the following code works:
SKPayment *paymentRequest = [SKPayment paymentWithProductIdentifier: #"track01"];
There are alot of different factors that can lead to the error, this is a good list of what can lead to failure here

How to make textfield accept decimal inputs in iphone

I have a calculator app in which I have a textfield in which if I enter any number; then it works fine. If I do not enter a number then it shows alert. I also want the user to be able to enter 1.5 but when I do this it shows alert "enter a number please"
So how can I enter decimal number? I am using the following code :
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789"] invertedSet];
NSString*string=costToClientTextField.text;
if ([string rangeOfCharacterFromSet:set].location != NSNotFound) {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"Only a number can be entered into this input field " delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
costToClientTextField.text=#"";
}
Add the "." in your set, like so
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber* candidateNumber;
NSString* candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];
range = NSMakeRange(0, [candidateString length]);
[numberFormatter getObjectValue:&candidateNumber forString:candidateString range:&range error:nil];
if (([candidateString length] > 0) && (candidateNumber == nil || range.length < [candidateString length])) {
return NO;
}
else
{
return YES;
}
}
Maybe this will help you. also put keyboard type number and punctuation.

UIAlert View-for yes/no condition

my app needs alert msg and if yes button pressed then one more alert msg and then i have to called a method.This is my code:
-(IBAction)resetPressed:(id)sender
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.tag ==1)
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
alert.tag =2;
[alert show];
[alert release];
}
else if(alertView.tag ==2)
{
[self resetArray];
}
}
Thanks.
I'm not sure what your goal is but a few things look wrong to me anyways:
First of all you should create your strings this way:
NSString *title= #"Warning";
There's no need to use stringWithFormat in your case.
Then, it doesn't seem you properly set the first UIAlert's tag to 1, and the default value for tags is 0 so I guess the if statements in didDismissWithButtonIndex are never true.
Also, you should check which button was pressed using buttonIndex, otherwise you are going to show both alert and call [self resetArray] whichever button is pressed by the user.
Hope that helps.
In your code, you create the first alert, but never actually set the tag on it. You should do:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
alert.tag = 1; //Or 2, or something.
[alert show];
[alert release];
Then the code in your delegate method will run.
Please define two separate UIAlertView in .h file
#interface XYZViewController:UIViewController
{
UIAlertView *firstAlertView;
UIAlertView *secondAlertView;
}
Now in your .m file modify as below:
-(IBAction)resetPressed:(id)sender
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
if(firstAlertView == nil)
{
firstAlertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
}
[firstAlertView show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView == firstAlertView)
{
NSString *title= [NSString stringWithFormat:#"Warning"];
NSString *message = [NSString stringWithFormat:#"Are you sure you want to Reset"];
NSString *ok = [NSString stringWithFormat:#"No"];
if(secondAlertView == nil)
{
secondAlertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:ok otherButtonTitles:#"Yes",nil];
}
[secondAlertView show];
}
else if(alertView == secondAlertView)
{
[self resetArray];
}
}
and in dealloc method please release the allocated UIAlertviews.
Hope i am clear to you.
Thanks,
Jim.

becomeFirstResponder not working!

In the below code becomeFirstResonder not working, only resignFirstresponder working...can anyone please help
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == txtDate)
{
[txtDate resignFirstResponder];
[txtTime becomeFirstResponder];
}
if (textField == txtTime)
{
[txtTime resignFirstResponder];
[txtAddress becomeFirstResponder];
}
if (textField == txtAddress)
{
[txtAddress resignFirstResponder];
[txtCity becomeFirstResponder];
}
if (textField == txtCity)
{
[txtCity resignFirstResponder];
[txtState becomeFirstResponder];
}
if(textField == txtState)
{
[txtState resignFirstResponder];
[txtZip becomeFirstResponder];
}
if (textField == txtZip)
{
[txtZip resignFirstResponder];
}
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if(textField == txtDate)
{
NSString *dateString = txtDate.text;
NSString *dateRegex = #"^(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/[0-9]{4}$";
NSPredicate *dateTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", dateRegex];
BOOL validateDate = [dateTest evaluateWithObject:dateString];
if(!validateDate){
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Date Error." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtDate.text = nil;
}
}
if(textField == txtTime)
{
NSString *timeString = txtTime.text;
NSString *timeRegex = #"^(([0]?[0-5][0-9]|[0-9]):([0-5][0-9]))$";
NSPredicate *timeTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", timeRegex];
BOOL validateTime = [timeTest evaluateWithObject:timeString];
if(!validateTime) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect Time Entry." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtTime.text = nil;
}
}
if(textField == txtAddress)
{
NSString *addressString = txtAddress.text;
NSString *addressRegex = #"^[a-z0-9 ]+$";
NSPredicate *addressTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", addressRegex];
BOOL validateAddress = [addressTest evaluateWithObject:addressString];
if(!validateAddress) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect State." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtAddress.text = nil;
}
}
if(textField == txtState)
{
NSString *stateString = txtState.text;
NSString *stateRegex = #"^(?-i:A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
NSPredicate *stateTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", stateRegex];
BOOL validateState = [stateTest evaluateWithObject:stateString];
if(!validateState) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect State." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtState.text = nil;
}
}
if(textField == txtCity)
{
NSString *cityString = txtCity.text;
NSString *cityRegex = #"^[a-z ]+$";
NSPredicate *cityTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", cityRegex];
BOOL validateCity = [cityTest evaluateWithObject:cityString];
if(!validateCity) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect City." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtCity.text = nil;
}
}
if(textField == txtZip)
{
NSString *zipString = txtZip.text;
NSString *zipRegex = #"^[0-9]{5}([- /]?[0-9]{4})?$";
NSPredicate *zipTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", zipRegex];
BOOL validateZip = [zipTest evaluateWithObject:zipString];
if(!validateZip) {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect Zip." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert2 show];
[alert2 release];
txtZip.text = nil;
}
}
return NO;
}
You should not do this in textFieldShouldReturn. Try doing this in textFieldDidEndEditing.
In
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
In
- (BOOL)textFieldDidEndEditing:(UITextField *)textField
{
if (textField == txtDate)
{
[txtTime becomeFirstResponder];
}
if (textField == txtTime)
{
[txtAddress becomeFirstResponder];
}
if (textField == txtAddress)
{
[txtCity becomeFirstResponder];
}
if (textField == txtCity)
{
[txtState becomeFirstResponder];
}
if(textField == txtState)
{
[txtZip becomeFirstResponder];
}
if (textField == txtZip)
{
//[txtZip resignFirstResponder];
}
}
You don't need the resignFirstResponder calls in there if you're assigning the firstResponder at the same time. That may be confusing things. Also, verify the fields are configured properly; are you able to tap on them to set their firstResponder status?
we must ensure the METHOD becomeFirstResponder be performed on mainThread
so make it like :
[xxx performSelectorOnMainThread:#selector(becomeFirstResponder) withObject:nil waitUntilDone:NO];