Keyboard doesn't hide in iOS even on resignFirstResponder - ios

I have a login page with username,password textfield and a submit button.
If the focus is on password textfield and the user presses the submit button without pressing the return key on keyboard.
The keyboard is dismissed as i uses resignFirstResponder to dismiss the keyboard but when i hit the server and the alert comes of invalid credentials,then within nano seconds when alert is shown,keyboard also appears.
Used the below line of code to dismiss keyboard on Login Button click.
[self.passwdTxtFld setDelegate:self];
[self.usernameTxtFld setDelegate:self];
[self.view endEditing:YES];
Below is the code from where i get the response from server and also displays the alert.
- (void)checkLogin
{
NSLog(#"???%#",self.usernameTxtFld.text);
NSDictionary *checkLogin=[pwInteract initializeWithOrgId:#"JVVC" AppId:#"JVVC" LoginId:self.usernameTxtFld.text Password:self.passwdTxtFld.text];
NSLog(#"checklogin is %#",checkLogin);
if(checkLogin)
{
if(![[checkLogin objectForKey:#"NOTIFICATION"]isEqualToString:#"Y"] && ![[checkLogin objectForKey:#"NOTIFICATION"]isEqualToString:#"NV"]){
[loggingInAlert dismissWithClickedButtonIndex:loggingInAlert.cancelButtonIndex animated:YES];
[loggingInAlert removeFromSuperview];
NSLog(#"?? response is %#",checkLogin);
NSString *result = [checkLogin objectForKey:#"IS_AUTH"];
NSString *error = [checkLogin objectForKey:#"ERROR"];
if ([result isEqualToString:#"Y"] )
{
if([self.usernameTxtFld.text isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:#"username"]]){
[[NSUserDefaults standardUserDefaults] setObject:#"olduser" forKey:#"usertype"];
}
else{
[[NSUserDefaults standardUserDefaults] setObject:#"newuser" forKey:#"usertype"];
}
[[NSUserDefaults standardUserDefaults]setObject:#"" forKey:#"fetch"];
[[NSUserDefaults standardUserDefaults]setObject:#"" forKey:#"state"];
[[NSUserDefaults standardUserDefaults]setObject:#"success" forKey:#"state"];
[[NSUserDefaults standardUserDefaults]setObject:self.usernameTxtFld.text forKey:#"username"];
[self performSegueWithIdentifier:#"success" sender:nil];
}
else if (![error isEqualToString:#""])
{
UIAlertView *networkAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
networkAlertView.tag = 1;
[networkAlertView show];
[self.view endEditing:YES];
if([self.passwdTxtFld isFirstResponder]){
NSLog(#"pass");
}
if([self.usernameTxtFld isFirstResponder]){
NSLog(#"ddd");
}
}
else if ([result isEqualToString:#""])
{
NSString *error = [checkLogin objectForKey:#"ERROR"];
UIAlertView *networkAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
networkAlertView.tag = 3;
[networkAlertView show];
}
else
{
UIAlertView *networkAlertView = [[UIAlertView alloc] initWithTitle:#"" message:#"Oops! Either Username or Password is incorrect. Please type correct Username and Password to proceed." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
networkAlertView.tag = 3;
[networkAlertView show];
}
}
else if([[checkLogin objectForKey:#"NOTIFICATION"]isEqualToString:#"NV"]){
[customAlert hideActivityIndicator];
}
}
else
{
UIAlertView *networkAlertView = [[UIAlertView alloc] initWithTitle:#"Server Error" message:#"No Response From Server." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
networkAlertView.tag = 3;
[networkAlertView show];
}
}
On click event of login button have resigned both the username and password textfield,also the UITextFieldDelegate are connected.

Mistake:-
According to your code you are just resigning your keyboard in one "else if" condition:-
else if (![error isEqualToString:#""])
{
UIAlertView *networkAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
networkAlertView.tag = 1;
[networkAlertView show];
[self.view endEditing:YES];
What about the others else if condition, Things will be resolved if you resign keyboard [self.view endEditing:YES] in the very first statement of (void)checkLogin method.

Try [self.view endEditing:YES] when you tap login button or just before you show alert.

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self view] endEditing:YES];
}
or try
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return YES;
}
// It is important for you to hide the keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
Also check UITextFieldDelegate delegate method

Related

Bug / Error with multiple UIAlertViews

I'm getting a really weird error when woking with UIAlertViews. Been pulling my hair out over this, please help me out!
The error occurs when I press "Create!" in the alert1 alert and checkUsernameExists returns true and then I press "K." in alert3.
Code
-(void) newProfile:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"New Profile"
message:nil
delegate:self
cancelButtonTitle:#"Create!"
otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
UITextField *username = [alert textFieldAtIndex:0];
username.keyboardType = UIKeyboardTypeDefault;
username.placeholder = #"Desired Username";
UITextField *password = [alert textFieldAtIndex:1];
password.keyboardType = UIKeyboardTypeDefault;
password.placeholder = #"Desired Password";
[alert1 show];
}
- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *title = [alert title];
UITextField *username = [alert textFieldAtIndex:0];
UITextField *passwrod = [alert textFieldAtIndex:1];
if ([title isEqualToString:#"New Profile"]) {
if ([self checkUsernameExists:username.text] == false) {
// Create new account
}
else {
[self errorPop:#"New Profile"];
}
}
}
-(void) errorPop:(NSString*)who {
if ([who isEqualToString:#"New Profile"]) {
UIAlertView *alert3 = [[UIAlertView alloc] initWithTitle:#"OH NOOOOO"
message:#"Username is already taken please try another one."
delegate:self
cancelButtonTitle:#"K."
otherButtonTitles:nil];
[alert3 show];
}
}
Logs
2014-07-30 19:57:49.594 App[6532:a0b] * Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason:
'textFieldIndex (0) is outside of the bounds of the array of text
fields'
The first alert view does not contain text fields, so when you request the first or second text field in -clickedButtonAtIndex:, you get an out of bounds exception.
You should distinguish which for which alert view you are receiving the callback. Try storing the alert views in a property upon creation, and then check for their identity in the callback before trying to access text fields.
Just set the delegate to nil for alert3 so it will not go under method "- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex".
Actually alert3 doesn't contain tetxfield and you have set delegate for this alert too so it is going to delegate method where they are trying to get UItextField but they don't have that's why it is crashing.

Multiple UIAlertViews to Enter Data

I have two buttons that will pop up an alertview with textfield to input data. However, only certain characters are allowed in each of the two textfields. Somehow, if I press the second button, the character set from the first button is used. What's going on here?
Also, what would be a more elegant form of inputting data without having to use an alertview? Could I use a modal view? If so, how?
- (IBAction)editRate
{
if(!self.powerOn) return;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Edit Jail Fee Rate"
message:#"Enter New Daily Rate"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[[alert textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeNumberPad];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != alertView.cancelButtonIndex)
{
UITextField *field = [alertView textFieldAtIndex:0];
field.placeholder = #"Enter New Rate";
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
if ([field.text rangeOfCharacterFromSet:set].location != NSNotFound)
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Only numbers are allowed in this field."delegate:self cancelButtonTitle:#"OK"otherButtonTitles:nil];
[errorAlert show];
FeeRate.text=#"0.00";
}
else
{
FeeRate.text = field.text;
[[NSUserDefaults standardUserDefaults] setObject:field.text forKey:RATE_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
else
{
}
}
- (IBAction)editDate
{
if(!self.powerOn) return;
UIAlertView *alertDate = [[UIAlertView alloc] initWithTitle:#"Edit Jail Fee Date"
message:#"Enter New Date"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
alertDate.alertViewStyle = UIAlertViewStylePlainTextInput;
[[alertDate textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeNumberPad];
[alertDate show];
}
- (void)alertDate:(UIAlertView *)alertDate clickedButtonAtIndex:(NSInteger)buttonIndex2
{
if (buttonIndex2 != alertDate.cancelButtonIndex)
{
UITextField *fieldDate = [alertDate textFieldAtIndex:0];
fieldDate.placeholder = #"Enter New Date";
NSCharacterSet * setnew = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789/"] invertedSet];
if ([fieldDate.text rangeOfCharacterFromSet:setnew].location != NSNotFound)
{
UIAlertView *errorAlert1 = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Only numbers and slashes are allowed in this field."delegate:self cancelButtonTitle:#"OK"otherButtonTitles:nil];
[errorAlert1 show];
FeeDate.text=#"00/00/0000";
}
else
{
FeeDate.text = fieldDate.text;
[[NSUserDefaults standardUserDefaults] setObject:fieldDate.text forKey:DATE_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
else
{
}
}
When a UIAlertView is dismissed then a function called
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
is called.
So, both your alert views call this function.
One way to tell which alertView is calling it, you could create an ivar or better two properties like this:
#property (nonatomic, strong) UIAlertView *rateAlert;
#property (nonatomic, strong) UIAlertView *dateAlert;
and you should initialize like this:
[self setRateAlert:[[UIAlertView alloc] initWithTitle...
[self.rateAlert show];
and
[self setDateAlert:[[UIAlertView alloc] initWithTitle...
[self.dateAlert show];
and then:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView==self.rateAlert) {
//do whatever for rateAlert
} else {
//do whatever with dateAlert
}
}

action on textFieldDidEndEditing

I want an alert when the following text fields receive the conditions in second section of code
self.circuit.rcdAtIan = [ICUtils nonNilString:self.rcdAtIan.text];
self.circuit.rcdAt5an = [ICUtils nonNilString:self.rcdAt5an.text];
The above code works fine so now I need to fire it. Using the below method was my first thought but that fires the alert on every keyboard resignation. I only want the alert to display once.
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([_rcdAtIan.text intValue]> 200) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alert show];
}
if ([_rcdAt5an.text intValue]> 40) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alert show];
}
}
Im thinking maybe I need a bool with NSUserDefaults perhaps? but not sure how to implement that to check if the alert has been shown. Normally if I wanted an alert shown once I would do
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:#"alert"]]){
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"alert"];
[[NSUserDefaults standardUserDefaults] synchronize];
[alert show];
}
However in this instance, when the page is reloaded I want the alerts to be shown again and in any case im not sure if thats an efficient way to solve this
Don't use NSUserDefaults, that would be inappropriate
in your #interface...
#property (assign) BOOL freshAlert1;
#property (assign) BOOL freshAlert2;
then something like this... (assuming 'page is reloaded' equates to your viewController coming back onscreen)
- (void)viewDidAppear
{
self.freshAlert1 = YES;
self.freshAlert2 = YES;
}
if (([_rcdAtIan.text intValue]> 200) && self.freshAlert1) {
self.freshAlert1 = NO;
...
}
if (([_rcdAt5an.text intValue]> 40) && self.freshAlert2) {
self.freshAlert2 = NO;
...
}
What exactly do you mean by "once"? Once per app run, once per editing step?
Or maybe simply add two BOOL flags that you can reset whenever you want and simply to
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([_rcdAtIan.text intValue]> 200 && !alert1shown) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
alert1shown = YES;
[alert show];
}
if ([_rcdAt5an.text intValue]> 40 && !alert2shown) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
alert2shown = YES;
[alert show];
}
}

UIAlertView keeps re-appearing after dismissWithClickedButtonIndex included in performSelector: withObject: afterDelay:

I have a button which I want to implement with password before triggering a segue if the password is correct. it all looks fine up to the moment when you type in wrong password and I have implemented another alertView to tell the user the password is wrong. When the alert view pops out and dismisses after some delay, it keeps re-appearing and disappearing and nothing else can be done on the screen!
How to stop the re appearing?
Below is my part of the code that deals with this:
- (IBAction)editLeagues:(id)sender {
[self presentAlertViewForPassword];
}
-(void)presentAlertViewForPassword
{
_passwordAlert = [[UIAlertView alloc]initWithTitle:#"Password"
message:#"Enter Password to edit Leagues"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[_passwordAlert setAlertViewStyle:UIAlertViewStyleSecureTextInput];
_passwordField = [_passwordAlert textFieldAtIndex:0];
_passwordField.delegate = self;
_passwordField.autocapitalizationType = UITextAutocapitalizationTypeWords;
_passwordField.tag = textFieldPassword;
[_passwordAlert show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSString *password = [NSString stringWithFormat:#"55555"];
if ( ![_passwordField.text isEqual:password]) {
_wrongPassword = [[UIAlertView alloc] initWithTitle:#"Wrong Password"
message:#"You are not authorised to use this feature!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
[_wrongPassword show];
[self performSelector:#selector(allertViewDelayedDissmiss:) withObject:nil afterDelay:2];
}
else
{
[self performSegueWithIdentifier:#"addLeague" sender:[alertView buttonTitleAtIndex:0]];
}
}
-(void) allertViewDelayedDissmiss:(UIAlertView *)alertView
{
[_wrongPassword dismissWithClickedButtonIndex:-1 animated:YES];
}
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
NSString *inputText = [[alertView textFieldAtIndex:0] text];
if( [inputText length] >= 4 )
{
return YES;
}
else
{
return NO;
}
}
[_wrongPassword dismissWithClickedButtonIndex:-1 animated:YES]; will call the delegate method alertView:didDismissWithButtonIndex:
You have two options:
don't set a delegate on the wrong password alert
check for the correct alert in alertView:didDismissWithButtonIndex: e.g.
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alert == _passwordAlert) {
NSString *password = [NSString stringWithFormat:#"55555"];
// and so on
}
}
Issue is causing because when you dismiss the wrong password alert it'll also call the didDismissWithButtonIndex delegate method.
Solution 1
Set the delegate of wrong password alert to nil.
wrongPassword = [[UIAlertView alloc] initWithTitle:#"Wrong Password"
message:#"You are not authorised to use this feature!"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:nil];
Solution 2
Add a tag to your alertView. And change your methods like:
-(void)presentAlertViewForPassword
{
_passwordAlert = [[UIAlertView alloc]initWithTitle:#"Password"
message:#"Enter Password to edit Leagues"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[_passwordAlert setAlertViewStyle:UIAlertViewStyleSecureTextInput];
passwordAlert.tag = 7;
_passwordField = [_passwordAlert textFieldAtIndex:0];
_passwordField.delegate = self;
_passwordField.autocapitalizationType = UITextAutocapitalizationTypeWords;
_passwordField.tag = textFieldPassword;
[_passwordAlert show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if(alertView.tag == 7)
{
NSString *password = [NSString stringWithFormat:#"55555"];
if ( ![_passwordField.text isEqual:password])
{
_wrongPassword = [[UIAlertView alloc] initWithTitle:#"Wrong Password"
message:#"You are not authorised to use this feature!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
[_wrongPassword show];
[self performSelector:#selector(allertViewDelayedDissmiss:) withObject:nil afterDelay:2];
}
else
{
[self performSegueWithIdentifier:#"addLeague" sender:[alertView buttonTitleAtIndex:0]];
}
}
}

Facebook Connect Graph API get notification when successfully sharing to facebook

I use this code to share to facebook:
[appDelegate.facebook dialog:#"feed" andParams:params andDelegate:appDelegate];
How can i get the notification (like sharekit) when sharing is successful?
I want to show UIAlertView but i do not know which facebook method that i need to put the UIAlertView.
I try in this method:
- (void)dialogDidSucceed:(NSURL *)url {
if ([_delegate respondsToSelector:#selector(dialogCompleteWithUrl:)]) {
[_delegate dialogCompleteWithUrl:url];
}
UIAlertView * alert=[[UIAlertView alloc]
initWithTitle: #"Sharing to Facebook"
message: #"Success"
delegate:self
cancelButtonTitle:#"Close"
otherButtonTitles:nil, nil];
[self setAlertSuccess:alert];
[alertSuccess show];
[alert release];
NSLog(#"SUCCESS 2");
[self dismissWithSuccess:YES animated:YES];
}
It is working however, when i click cancel button, this method is also called. So where is the right one to put the success alert view?
I am new in IOS.
These are changes i made in FBDialog.m
- (void)dismissWithSuccess:(BOOL)success animated:(BOOL)animated {
if (success) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Facebook Login Sucessful!" message:#"" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
if ([_delegate respondsToSelector:#selector(dialogDidComplete:)]) {
[_delegate dialogDidComplete:self];
}
} else {
if ([_delegate respondsToSelector:#selector(dialogDidNotComplete:)]) {
[_delegate dialogDidNotComplete:self];
}
}
[self dismiss:animated];
}

Resources