There is a view controller on my app in which the user enters personal information. There is a cancel option that pulls up an alert notifying them they will lose the data if it is not saved. I only want to display this alert if any text field in this view controller has [.text.length > 0] (I have about 20 text fields, if any have even 1 character it should pull up the alert). I could manually name every text field in an if statement but was hoping there was some way to check all the text fields in my view controller?
Here's what I have so far:
for (UIView *view in [self.view subviews]) {
if ([view isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField *)view;
if(textField.text.length >= 1){
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Cancel?"
message:#"If you leave before saving, the athlete will be lost. Are you sure you want to cancel?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alertView show];
}
if(textField.text.length == 0){
[[self navigationController] popViewControllerAnimated:YES];
}
}
}
I want to check if there are any text fields with value but this causes errors because its checking if textField.text.length == 0 before it finishes the for loop.
SOLUTION:
BOOL areAnyTextFieldsFilled = NO;
for (UIView *view in [self.view subviews]) {
if ([view isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField *)view;
if(textField.text.length >= 1){
areAnyTextFieldsFilled = YES;
}
}
}
if(areAnyTextFieldsFilled == YES){
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Cancel?"
message:#"If you leave before saving, the athlete will be lost. Are you sure you want to cancel?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alertView show];
}
else{
[[self navigationController] popViewControllerAnimated:YES];
}
You can achieve something very nice with tags. Set each one to a certain tag 1, 2, ... , 20. Then, iterate through with something like this:
for (int x = 1; x < 21; x++)
{
UITextField *aTextField = (UITextField *) [self.view viewWithTag:x];
//check here if text
}
Also, for additional efficiency, you could set a flag that starts as zero and if a user edits a textField, it will change to one. Then it would only loop if it is one.
However, for your current method what you could do is have a flag (yes, again, I love them :) ) And set it to zero before hand (probably in viewDidLoad). If you run into a text field with words, set it to 1. Erase the current if(textField.text.length == 0) statement. Then, afterwards just check if the flag still == 0 after the loop.
Related
I want to Aligned my message text in UIAlertView and here is my code but when i running this code the text appear as before and nothing change after for loop. i also want to increase my text? I am using this code Align text in a UIAlertView that has a scrollbar right now.
UIAlertView *alret = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"%#",[title objectAtIndex:indexPath.row]]
message:[NSString stringWithFormat:#"%#",[description objectAtIndex:indexPath.row]]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
for(id subview in alret.subviews) {
if([subview isKindOfClass:[UITextView class]]) {
[(UITextView *)subview setTextAlignment:NSTextAlignmentJustified];
}
}
[alret show];
Try this
for (UIView *view in alert.subviews) {
if([[view class] isSubclassOfClass:[UILabel class]]) {
((UILabel*)view).textAlignment = NSTextAlignmentLeft;
}
}
Hope it helps.
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];
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 have an iOS app that I recently updated to deal with the UIAlertView / SubView issue that causes the textboxes to render as clear or white (or not render at all, not sure which). In any case, this is a relatively simple question as I'm kind of new to Obj-C, but how do I get the value of the new textbox from another call in the app?
Here is my UIAlertView:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Password"
message:#"Enter your Password\n\n\n"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Login", nil];
alert.frame = CGRectMake( 0, 30, 300, 260);
It used to be stored as a UITextField, and then added to the UIAlertView as a subview:
psswdField = [[UITextField alloc] initWithFrame:CGRectMake(32.0, 65.0, 220.0, 25.0)];
psswdField.placeholder = #"Password";
psswdField.secureTextEntry = YES;
psswdField.delegate = self;
psswdField.tag = 1;
[psswdField becomeFirstResponder];
[alert addSubview:psswdField];
[alert show];
[alert release];
This is all commented out now, and instead I have it rewritten as:
alert.alertViewStyle = UIAlertViewStyleSecureTextInput;
This is how I used to retrieve the value:
[psswdField resignFirstResponder];
[psswdField removeFromSuperview];
activBkgrndView.hidden = NO;
[activInd startAnimating];
[psswdField resignFirstResponder];
[self performSelectorInBackground:#selector(loadData:) withObject:psswdField.text];
Now I'm a bit confused as to how I get the value from that textbox to send to loadData.
You don't want to add your own text field to the alert view. You're not supposed to directly add subviews to a UIAlertView. There is an alertViewStyle property on UIAlertView that you want to set to UIAlertViewStyleSecureTextInput, which will add a text field for you. So you would set it with a line like this:
alert.alertViewStyle = UIAlertViewStyleSecureTextInput;
Then you will retrieve the value in this text field using the delegate method - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex, which you must add to the class that you're setting as your UIAlertView delegate. Here is an example implementation of that delegate method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
// Make sure the button they clicked wasn't Cancel
if (buttonIndex == alertView.firstOtherButtonIndex) {
UITextField *textField = [alertView textFieldAtIndex:0];
NSLog(#"%#", textField.text);
}
}