So this is happening.
I have one view controller and it handles all of the alert views in my app. I have another view controller that has a UITextView that the user can edit, and a save button.
When they hit the save button, if the text is already saved, it triggers an alert that asks them if they're sure they want to update, and if they confirm, it updates the file and gives them a second alert that says it was a success.
What's happening is that the keyboard keeps popping up when the second alert appears. I've tried resigning the keyboard and turning off the user interaction enabled flag on the text field as soon as the save button is hit.
self.storyEditorTextView.userInteractionEnabled=NO;
[self.storyEditorTextView resignFirstResponder];
I've also tried to turn it off when the alert is responded to (since some alerts can have a textfield).
To make matters worse, when I comment out the resign and userInteractionsEnabled lines, including the one in the alert, the keyboard still appears after the first alert is dismissed, disappears when the second alert is dismissed (if you can tap it because the keyboard covers it), and you can't tap into the UITextView and bring up the keyboard without going back to the parent view.
Here's the alert code.
- (void)addPromptToFavorites
{
// throw up an alert to confirm and get a name
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Name Your Favorite!"
message:#"Would you like to add a name to your prompt?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK",nil];
// add a text field
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField *textField = [alert textFieldAtIndex:0];
textField.text = #"My Great Prompt";
// set the tag
[alert setTag:SAVE_FAVE];
// Display the alert to the user
[alert show];
}
- (void)updateFave: (NSNumber *) theFaveId
{
NSLog(#"UPDATE FAVE\n\nself.sharedFaveMan.tempFave %#",self.sharedFaveMan.tempFave);
// NSMutableDictionary *faveDict =[[NSMutableDictionary alloc] init];
// loop through the favoritePrompts array until you find a match to the faveID
for (id element in self.sharedFaveMan.favoritePrompts) {
NSNumber *valueForID = [element valueForKey:#"id"];
if([valueForID isEqualToNumber:theFaveId])
{
self.sharedFaveMan.tempFave=element;
}
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Update Your Favorite!"
message:#"The story will be saved with the currently selected Favorite."
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK",nil];
//set the tag
[alert setTag:UPDATE_FAVE];
// Display the alert to the user
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
UITextField *textField = [alertView textFieldAtIndex:0];
[textField resignFirstResponder];
if (buttonIndex !=0)
{
if(alertView.tag==UPDATE_FAVE)
{
NSLog(#"Updating Fave");
// loop through the favoritePrompts array until you find a match to the faveID
int counter=0;
for (id element in self.sharedFaveMan.favoritePrompts) {
NSNumber *valueForID = [element valueForKey:#"id"];
if([valueForID isEqualToNumber:self.sharedFaveMan.theFaveID]){
break;
}
counter ++;
}
// update the pieces of the prompt
[[self.sharedFaveMan.favoritePrompts objectAtIndex:counter] setObject:self.sharedFaveMan.faveStoryText forKey:#"storyText"];
// save it
[self saveFavorites];
[[NSNotificationCenter defaultCenter]
postNotificationName:#"updateTheTable"
object:self];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Success!"
message:#"Favorite Updated!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"OK",nil];
//play a sound
[self createSoundID: #"ticktock.aiff"];
//set the tag
[alert setTag:UPDATE_COMPLETE];
// Display the alert to the user
[alert show];
}
}
else if (buttonIndex == 0)
{
NSLog(#"%ld",(long)alertView.tag);
if(alertView.tag==SAVE_FAVE)
{
// they canceled the save
}
else if (alertView.tag==UPDATE_COMPLETE)
{
NSLog(#"Hit that");
[[NSNotificationCenter defaultCenter]
postNotificationName:#"dismissedDialogNotification"
object:self];
}
}
}
-(BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
UITextField *textField = [alertView textFieldAtIndex:0];
if (textField && [textField.text length] == 0)
{
return NO;
}
return YES;
}
Any ideas?
Here is the code
- (void)textViewDidEndEditing:(UITextView *)textView {
[textView resignFirstResponder];
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return NO;
}
// For any other character return TRUE so that the text gets added to the view
return YES;
}
-(BOOL)textViewShouldEndEditing:(UITextView *)textView {
[textView resignFirstResponder];
return true;
}
and in alert method at the begining add this line of code
[self.view endEditing:YES];
Related
I have two textfield(name and phone#).Once user is registered, user should not able to edit phone number textfield. I am checking the condition when user click on phone number textfield. if registered I am creating alert saying that "Cannot edit". When i click on "ok" i dismiss the keypad. I am using the following code to do so
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(registered)
{
dismissAlert = [[UIAlertView alloc]initWithTitle:#"cannot edit" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[dismissAlert show];
}
}
if([title isEqualToString:#"OK"])
{
[self.view endEditing:YES];
[self.PhoneNumber resignFirstResponder];
dismissAlert = nil;
}
But textFieldShouldBeginEditing called multiple times. It happens only in iPad.
Try this -
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField == txtPhone)
{
[self performSelector:#selector(phoneAlert) withObject:nil afterDelay:0.1];
return NO;
}
return YES;
}
-(void)phoneAlert
{
dismissAlert = [[UIAlertView alloc]initWithTitle:#"cannot edit" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[dismissAlert show];
}
Finally, i got it. I set
self.PhoneNumber.userInteractionEnabled = NO;
Is there any way to judge whether there is currently a UIAlertView instance showing? Because it is possible to show multiple UIAlertView in the same window level.
if ([self isAlertViewShowing]) {
// do not show UIAlertView again.
} else {
// show your UIAlertView.
}
Hope there is such a method called isAlertViewShowing or something else.
Method 1-
Initialize default flag for alert... If alert is not open set isAlertViewShowing as NO
Bool isAlertViewShowing;
isAlertViewShowing = NO;
if (isAlertViewShowing == NO){
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
// Now set isAlertViewShowing to YES
isAlertViewShowing = YES;
}
else
{
//Do something
}
Method 2-
Make your own function to check whether any UIAlertView is showing or not
- (BOOL)isAlertViewShowing{
for (UIWindow* window in [UIApplication sharedApplication].windows) {
NSArray* subviews = window.subviews;
if ([subviews count] > 0){
for (id view in subviews) {
if ([view isKindOfClass:[UIAlertView class]]) {
return YES;
}
}
}
}
return NO;
}
I recommended to use second method if number of UIAlertView instance
may be more than one.
I am using a custom UIAlertView. When the error pops up, I resignedFirstResponder as I wanted. The problem comes about when the user clicks the done button designated by kButtonTitle seen below. I am trying to get the keyboard to pop back up once the user clicks the button recognizing the error. I attempted:
if (alert)
[textField resignFirstResponder];
else
[_nameTextField becomeFirstResponder];
}
The above didn't seem to change anything. My entire code for the textFieldShouldReturn method is pasted below:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSString *name = _nameTextField.text;
if ((name.length > 6) && [name containsString:#" "])
{
[textField resignFirstResponder];
} else {
SCLAlertView *alert = [[SCLAlertView alloc] init];
alert.backgroundType = Blur;
NSString *kNoticeTitle = #"Error";
[alert showNotice:self title:kNoticeTitle subTitle:#"Please input both your first and last name" closeButtonTitle:kButtonTitle duration:0.0f];
if (alert)
[textField resignFirstResponder];
else
[_nameTextField becomeFirstResponder];
}
return YES;
}
Any help or comments are greatly appreciated! Thanks in advance!
Maybe you can use a button with a custom action instead of the default close button.
[textField resignFirstResponder];
SCLAlertView *alert = [[SCLAlertView alloc] init];
[alert addButton:kButtonTitle actionBlock:^{
[_nameTextField becomeFirstResponder];
}];
[alert showNotice:self title:kNoticeTitle
subTitle:#"Please input both your first and last name"
closeButtonTitle:nil duration:0.0f];
I am currently using the following to use a popup alert which allows the user to set a delay in seconds;
The input itself works fine, but the number is not remembered, so if I put 5, or 10, when I press 'set' it just ignores that value and goes to instant recording again. here is the IBAction to call the setDelay, and below it, I have posted the Alertview
-(IBAction)setDelay:(id)sender
{
// open a alert with text field, OK and cancel button
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Set delay in seconds" message:#" "
delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Set", nil];
CGRect frame = CGRectMake(14, 45, 255, 23);
if(!delayTextField) {
delayTextField = [[UITextField alloc] initWithFrame:frame];
delayTextField.borderStyle = UITextBorderStyleBezel;
delayTextField.textColor = [UIColor blackColor];
delayTextField.textAlignment = UITextAlignmentLeft;
delayTextField.font = [UIFont systemFontOfSize:14.0];
delayTextField.backgroundColor = [UIColor redColor];
delayTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
delayTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation; // use the default type input method (entire keyboard)
delayTextField.returnKeyType = UIReturnKeyDefault;
delayTextField.delegate = self;
delayTextField.clearButtonMode = UITextFieldViewModeWhileEditing; // has a clear 'x' button to the right
}
else
{
delayTextField.text=#"";
}
alert.delegate=self;
[alert addSubview:delayTextField];
[alert setAlertViewStyle:UIAlertViewStylePlainTextInput];
[alert show];
[alert release];
}
//
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.tag==100)
{
if (buttonIndex!=alertView.cancelButtonIndex)
{
[self featureButtonPressed];
}
}
else
{
if (buttonIndex==alertView.cancelButtonIndex)
{
self.delayTextField.text=#"";
}
}
}
From iOS 7 you can't add subviews to UIAlertView anymore -
UIAlertView addSubview in iOS7.
But if you need just simple UITextField in your UIAlertView you can just set UIAlertView style to UIAlertViewStylePlainTextInput and retrieve value from that field later. Eg.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Set delay in seconds" message:#" "
delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Set", nil];
alert.delegate=self;
[alert addSubview:delayTextField];
[alert setAlertViewStyle:UIAlertViewStylePlainTextInput];
[alert show];
then in your delegate method:
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.tag==100)
{
if (buttonIndex!=alertView.cancelButtonIndex)
{
[self featureButtonPressed];
}
}
else
{
if (buttonIndex==alertView.cancelButtonIndex)
{
UITextField *alertViewTextField = [alertView textFieldAtIndex:0];
//Do something with alertViewTextField.text value
}
}
}
#Guferos answer is absolutetly correct. It doesn't work because iOS 7 doesnt support this.
But in case you need more than a simple TextView, you can use a framework such as https://github.com/jdg/MBProgressHUD
:)
If I tap an image,can I pop up the UITextfield for entering the data? How would I do that?
You could use a UIAlertView as follows:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title"
message:#"Please enter your text:"
delegate:self
cancelButtonTitle:#"Done"
otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField *textField = [alert textFieldAtIndex:0];
textField.keyboardType = UIKeyboardTypeDefault;
textField.placeholder = #"Enter some text";
[alert show];
Edit: to handle the returned text, implement the delegate method
- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex > 0) {
UITextField *textField = [alert textFieldAtIndex:0];
NSString *text = textField.text;
if(text == nil) {
return;
} else {
//do something with text
}
}
}
You could add a UITapGestureRecognizer to your UIImageView .. on its selector action you add a textField to your view .. just in that simple your implmentation will be. and don't forget to set userInterActionEnabled = YES for the imageView since the default value is NO.