I have a Customized UIAlertView.I have a UITextField in that AlertView, which becomes the firstResponder as soon as it is shown. Now I need to dismiss the keyboard for that UITextField when user touches somewhere else in the AlertView. I have touchesBegan event for that.
Everything is in place and works fine, except when I call resignFirstResponder on the UITextField, it resigns from being the first responder but the keyboard is not dismissed. Is there any way to dismiss that keyboard.
I was looking for the solutions and found a similar post here with no answers
If anyone was able to find a way out please let me know. I even tried the following way, but its not working
UIWindow* tempWindow;
// Because we cant get access to the UIKeyboard throught the SDK we will just use UIView.
// UIKeyboard is a subclass of UIView anyways
UIView* keyboard;
// Check each window in our application
for(int c = 0; c < [[[UIApplication sharedApplication] windows] count]; c ++)
{
// Get a reference of the current window
tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:c];
for(int i = 0; i < [tempWindow.subviews count]; i++)
{
// Get a reference to the current view
keyboard = [tempWindow.subviews objectAtIndex:i];
// Loop through all views in the current window
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES){
[keyboard removeFromSuperview];
}
}
}
You must call resignFirstResponder on the UIAlertField,
eg:
[textField resignFirstResponder];[alertView resignFirstResponder];
Are you using custom code to show the keyboard? If not, try using the code from this StackOverflow question. I suspect that the resignFirstResponder message is not getting to the right control.
(The code in that answer is generally useful and sorely lacking from the SDK, IMHO.)
[self resignFirstResponder];
self means UIAlertView.
In my case it works.
There's no need to send a resignFirstResponder to the UIAlertView subclass. Just override becomeFirstResponder to return NO in UIAlertView subclass.
Apparently when you resign first responder on the UITextField, the UIAlertView becomes the next responder, keeping the Keyboard in place for some obscure reason.
Resigning that one too makes the keyboard disappear or better indeed override the becomeFirstResponder to return NO.
In my case this solution makes the UIAlertview animate to the upper left corner and animates back in place immediately after which looks very ugly and I cannot seem to find out why this is, but maybe someone else has some thoughts on that?
Here is my code extract in a class derived from UIAlertView:
- (BOOL)becomeFirstResponder
{
return NO;
}
- (void)someCustomButtonClicked:(id)sender
{
[textField resignFirstResponder];
// ...
}
-[UIView endEditing:]
http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/endEditing:
(Extra text because Stack Overflow requires at least 20 characters.)
Try these methods
-(void)viewDidLoad
{
[super viewDidLoad];
UIAlertView *loginAlert = [[UIAlertView alloc] initWithTitle:#"Welcome" message:#"Please Enter Login and Password" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[loginAlert setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];
[loginAlert textFieldAtIndex:0].delegate = self;
[loginAlert textFieldAtIndex:1].delegate = self;
[loginAlert setTag:777];
[loginAlert show];
[loginAlert release];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
And you should add the UITextFieldDelegate in the header file.
I met the problem just now.
Here's how I've solved the problem:
First, make your textField.delegate = self;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Title" message:nil delegate:self cancelButtonTitle:#"cancel" otherButtonTitles:#"OK", nil, nil];
UITextField *oldPassWord = [alertView textFieldAtIndex:0];
oldPassWord.delegate =self;
UITextField *newPassWord = [alertView textFieldAtIndex:1];
newPassWord.delegate =self;
[alertView show];
Then, [textField resignFirstResponder];
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
[[alertView textFieldAtIndex:buttonIndex]resignFirstResponder];
}
Related
As I type into a textbox on a UIAlertView, an ImageButton in the background starts shearing through. It only happens when the text gets close to the image.
The code for the alertview is as follows:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"... number"
message:nil
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
[alert setAlertViewStyle:UIAlertViewStylePlainTextInput];
[[alert textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeNumberPad];
[[alert textFieldAtIndex:0] becomeFirstResponder];
[alert setTag:1];
[alert setOpaque:true];
[alert show];
//EDIT
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 2)
{
NSString* title = [alertView buttonTitleAtIndex:buttonIndex];
if ([title isEqualToString:#"Cancel"])
{
[self doSomething1];
}
if([alertView.title isEqualToString:#"Are you sure?"] && [title isEqualToString:#"YES"])
{
[self doSomething2];
}
}
}
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
if (alertView.tag == 1){
NSString *inputText = [[alertView textFieldAtIndex:0] text];
if( [inputText length] == 10 )
{
NSUserDefaults* def = [NSUserDefaults standardUserDefaults];
[def setObject:inputText
forKey:#"FIELD"];
[def synchronize];
return YES;
}
else
{
return NO;
}
}
return YES;
}
I have tried setting it to opaque, I have tried looking for z-indexing values, and I have also tried scaling the image down to the smallest it needs to be. Taking screenshots does not help. This only happens in iOS 7.
UIAlertView are not shown in the same UIWindow as the rest of your view controllers. They are shown in their own UIWindow with a windowLevel of UIWindowLevelAlert. This other window is transparent (mostly) and renders on top of your main window. This makes UIAlertView objects not interact as well with other views you may have on screen. Do not modify any properties from the underlying UIView class.
The code you show above has if (alertView.tag == 1) as well as if (alertView.tag == 2), but it only ever creates a UIAlertView with a tag value of 1. Is there somewhere else you are creating a second alert? Are you possibly showing a second alert before the first one completes its disappearance animation? That has been known to cause graphical tears.
The delegate method -alertViewShouldEnableFirstOtherButton: can be called from within the -drawRect: method of the UIAlertView. The draw method must be extremely fast to avoid causing graphical tearing. Yours calls NSUserDefaults -synchronize, which performs a disk write operation. You should not perform any operation within your -alertViewShouldEnableFirstOtherButton: method, besides determining the response value. If you want to be notified of changes to the text field, assign yourself as the UITextFieldDelegate and implement -textField:shouldChangeCharactersInRange:replacementString:. That method should be safe to call NSUserDefaults -synchronize from.
As an additional tip, you could make your code much easier to manage using the PSPDFAlertView.
I have an alert view with a uitextfield added as a subview.
In my uitableview controller the keyboard shows fine.
However in a different view I wanted to do the same thing. So instead of using a UITableView Controller I made it a UIViewController so that I could add a toolbar at the bottom of the view.
But when I display the UIAlertView the keyboard is hidden. I'm thinking it's behind the view because the alert view moves up to make room for the keyboard.
Any ideas?
UPDATE:
The reason the keyboard was being hidden was because I was dismissing a modalviewcontroller after showing the alert. For some reason it would dismiss the keyboard also I guess. Just rearranged the order an fit works fine now...
Try implementing the didPresentAlertView: method and inside set the text field to firstResponder like so:
- (IBAction)someActionThatTriggersAnAlertView:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"TITLE" message:#"MESSAGE" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Done", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField *someTextField = [alert textFieldAtIndex:0];
someTextField.keyboardType = UIKeyboardTypeAlphabet;
someTextField.keyboardAppearance = UIKeyboardAppearanceAlert;
someTextField.autocorrectionType = UITextAutocorrectionTypeNo;
[alert show];
[alert release];
}
#pragma mark - UIAlertViewDelegate Methods
- (void)didPresentAlertView:(UIAlertView *)alertView {
[[alertView textFieldAtIndex:0] becomeFirstResponder];
}
UIAlertView Documentation
UIAlertViewDelegate Documentation
I have create UITextField with alert view. After typing on UITextField I want to hide keyboard when user click "done" button.
This is my code. When I run it it's hitting the hideKeyBoard method (I found out using NSLog and the debugging). But this code not hiding the keyboard. Please Help me.
- (IBAction)doAlertInput:(id)sender
{
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc]
initWithTitle: #"Please Enter Your Email Address!" message:#"You won’t see me"
delegate: self cancelButtonTitle: #"Ok" otherButtonTitles: nil];
userInput=[[UITextField alloc] initWithFrame: CGRectMake(12.0, 70.0, 260.0, 25.0)];
userInput.returnKeyType = UIReturnKeyDone;
[userInput addTarget:self action:#selector(hideKeyBoard) forControlEvents:UIControlEventEditingDidEndOnExit];
[userInput setBackgroundColor:[UIColor whiteColor]];
[alertDialog addSubview:userInput];
[alertDialog show];
[alertDialog release];
}
-(void)hideKeyBoard
{
[userInput resignFirstResponder];
NSLog(#"Key Board Hid");
}
I think you're missing the delegate for your UITextField
userInput.delegate = self;
also implement the protocol and that should be it. Cheers.
After appering the key board its covering the alert view. So what i am doing is shift up my alert view little higher. Then it will be not a problem because key board doesn't cover the alert view any more.
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0.0, 130.0);
[myAlertView setTransform:myTransform];
The first parameter of CGAffineTransformMakeTranslation() is the X coordinate to move the origin of the view to. The second parameter is the Y location to move the origin of the view to. 130.0 doesn't exactly center the alert view between the status bar and the keyboard.
You'll need to add these two lines somewhere between the UIAlertView instantiation and the [UIAlertView show] line. I put them directly before the show line.
Also add the CoreGraphics framework to your project.
I think this will help you. Thank you :)
You can also use this method.
First set delegate method in your .h file
UITextfieldDelegate using <>
and then in your .m file.
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Make sure do not forget to add textfield delegate,otherwise method -(BOOL) will not appear.
I have a UIDatePickerView inside UIActionSheet as a input to the UITextField. When focusing on UITextField UIActionSheet will popup instead of Keyboard. When clicking on the done button in the UIActionSheet it'll hide. I have several other text fields behave as normal (Showing keyboard).
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if ([textField isEqual:txtExpDate]) {
[textField resignFirstResponder];
[self showDatePicker];
}
}
- (void) showDatePicker{
UIActionSheet *datePickerActionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:#"Done" otherButtonTitles:nil];
datePickerView = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 80, 0, 0)];
datePickerView.datePickerMode = UIDatePickerModeDate;
[datePickerActionSheet addSubview:datePickerView];
[datePickerActionSheet showInView:self.navigationController.view];
[datePickerActionSheet setBounds:CGRectMake(0, 0, 320, 500)];
[datePickerActionSheet release];
}
Now my problem is, Let say first user taps on normal textfield. Which will popups keyboard. Then without selecting done button he taps on date field. Which will popup action sheet (without dismissing the keyboard). After hiding actionsheet user has to tap on other text filed and click on return key of the keyboard.
I want to hide the keyboard if action sheet is going to popup?
Make the text field resignFirstResponder when you are going to bring up the action sheet. If you have more than one text fields, create an instance variable of type UITextField in .h file.
UITextField *currentTextField;
Then you can keep reference of the current text field in textFieldDidBeginEditing: method.
- (void)textFieldDidBeginEditing:(UITextField *)textField {
currentTextField = textField;
....
And, call [currentTextField resignFirstResponder] in showDatePicker method.
- (void)showDatePicker {
[currentTextField resignFirstResponder];
UIActionSheet *datePickerActionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:#"Done" otherButtonTitles:nil];
...
EDIT: #Samuel Goodwin is correct. We don't have to track the text fields. We can simply do the following to dismiss the keyboard.
- (void)showDatePicker {
[self.view endEditing:YES];
...
If you want to dismiss the keyboard for any reason, simply do:
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) target:nil forEvent:nil];
Worked for all text fields everywhere anywhere.
The method proposed by EmptyStack did not work for me (using xcode 4.2). I placed the message [currentTextField resignFirstResponder] in the method willPresentActionSheet:(UIActionSheet *)actionSheet, that also didn't work. Then I put the message in actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex and that did the trick... strange!
I know this is a very old post but I just thought I'd add the solution that worked for me (the others didn't). I found that I had to re-assign a text field to be first responder the resign it again. It doesn't matter which text field becomes then looses first responder status, this is just a way to ditch that keyboard.
[self.textfield becomeFirstResponder];
[self.textfield resignFirstResponder];
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if ([textField isEqual:txtExpDate]) {
[self showDatePicker];
return NO;
}
return YES;
}
It is working fine.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if(textField==myTextField2){
[myTextField1 resignFirstResponder];
[self showActionSheet];
return NO;
}
return YES;
}
I'm having a similar issue to Anthony Chan's question, and after trying every suggested solution, I'm still stuck.
Somehow, only after interacting with my UIAlertView, I'm unable to dismiss the keyboard in another view of my app. It's as though the Alert is breaking my UITextField's ability to resignFirstResponder. Below I instantiate my UIAlertView, which then calls its didDismissWIthButtonIndex method. Then, I call the showInfo method, which loads another UIViewController.
UIAlertView *emailFailAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"error message text."
delegate:self
cancelButtonTitle:#"Not now"
otherButtonTitles:#"Settings", nil];
[emailFailAlert setTag:2];
[emailFailAlert show];
[emailFailAlert release];
Once the 'Settings' option is pressed, I'm calling this method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if ([alertView tag] == 2) {
if (buttonIndex == 1){
[self showInfo:nil];
}
}
}
My showInfo method loads the other ViewController, via the code below:
- (IBAction)showInfo:(id)sender {
FlipsideViewController *fscontroller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
fscontroller.delegate = self;
fscontroller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:fscontroller animated:YES];
[fscontroller release];
}
Upon clicking any textField in this Flipside VC, I'm unable to dismiss the keyboard as I normally can with - (BOOL)textFieldShouldReturn:(UITextField *)textField, and [textField resignFirstResponder]. I've omitted this code bc this question is getting long, but I'm happy to post if necessary.
The interesting part is that if I comment out the [self showInfo:nil] call made when the button is clicked and call it by clicking a test button (outside the alertView didDismissWithButtonIndex: method), everything works fine. Any idea what's happening here?
Thanks in advance!
When an alert, with more than one dismissal option, is called above a keyboard - the keyboard becomes un-dismissible with resignFirstResponder on the active textfield;
You will need to dismiss the keyboard before showing the alert.
Assuming your UITextField is called myTextField;
[myTextField resignFirstResponder]; //That's the only line I added
UIAlertView *emailFailAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"error message text."
delegate:self
cancelButtonTitle:#"Not now"
otherButtonTitles:#"Settings", nil];
[emailFailAlert setTag:2];
[emailFailAlert show];
[emailFailAlert release];
I hope this helps anyone who had to deal with this oddly obscure issue.
You should not call alertView:didDismissWithButtonIndex: directly. This delegate method will be executed automatically in all cases after the alert has disappeared. Otherwise the code will be run twice!