8

I am trying to get the text from the UIAlertController textfield. Can someone tell me what I did wrong as its not working. I get a NIL return.

- (IBAction)btnMakeRec {

        UIAlertController *alert= [UIAlertController
                                   alertControllerWithTitle:@"Recipe Name?"
                                   message:@""
                                   preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                   handler:^(UIAlertAction * action){


                                               UITextField *temp = alert.textFields.firstObject;

                                               RecipeDesc.text = temp.text;
                                               // HERE temp is Nil


                                               RDescription = [[NSString alloc ] initWithFormat:@"%@", RecipeDesc.text];


                                                   }];

        UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault
                                                       handler:^(UIAlertAction * action) {

                                                         //  NSLog(@"cancel btn");

                                                           [alert dismissViewControllerAnimated:YES completion:nil];

                                                       }];

        [alert addAction:ok];
        [alert addAction:cancel];

        [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
            textField.placeholder = @"Enter the name of the recipe";
            textField.keyboardType = UIKeyboardTypeDefault;
        }];

        [self presentViewController:alert animated:YES completion:nil];

    }

}
Mark Worsnop
  • 4,407
  • 15
  • 54
  • 79
  • Try to insert `NSLog(@"alert.textFields: %@", alert.textFields);` in the same block. – bauerMusic Dec 30 '14 at 04:23
  • OK I did the NSLog and got this: alert.textFields: ( "<_UIAlertControllerTextField: 0x7b941230; frame = (4 4; 229.333 16); text = 'yyyy'; clipsToBounds = YES; opaque = NO; gestureRecognizers = ; layer = >" ) See the text="yyyy" that is what I entered. So how to get get that text into my string? – Mark Worsnop Dec 30 '14 at 16:36

1 Answers1

35

Here's the 'clean copy/paste' version:

Swift 3+:

let alert = UIAlertController(title: "Alert Title",
                              message: "Alert message",
                              preferredStyle: .alert)

let ok = UIAlertAction(title: "OK",
                       style: .default) { (action: UIAlertAction) in
                        
                        if let text = alert.textFields?.first?.text {
                            
                            print("And the text is... \(text)")
                            
                        }
                        
                        
}

let cancel = UIAlertAction(title: "Cancel",
                           style: .cancel,
                           handler: nil)

alert.addTextField { (textField: UITextField) in
    
    textField.placeholder = "Text here"
    
}

alert.addAction(ok)
alert.addAction(cancel)

self.present(alert, animated: true, completion: nil)

Swift 2:

let alert = UIAlertController(title: "Alert Title",
                              message: "Alert message",
                              preferredStyle: UIAlertControllerStyle.Alert)

let ok = UIAlertAction(title: "OK",
                       style: UIAlertActionStyle.Default) { (action: UIAlertAction) in
                        
                        if let alertTextField = alert.textFields?.first where alertTextField.text != nil {
                            
                            print("And the text is... \(alertTextField.text!)!")
                            
                        }
                        
                        
}

let cancel = UIAlertAction(title: "Cancel",
                           style: UIAlertActionStyle.Cancel,
                           handler: nil)

alert.addTextFieldWithConfigurationHandler { (textField: UITextField) in
    
    textField.placeholder = "Text here"
    
}

alert.addAction(ok)
alert.addAction(cancel)

self.presentViewController(alert, animated: true, completion: nil)

Objective C:

UIAlertController *alert = [UIAlertController
                           alertControllerWithTitle: @"Alert Title"
                           message: @"Alert message"
                           preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *ok = [UIAlertAction actionWithTitle: @"OK" style: UIAlertActionStyleDefault
                                           handler:^(UIAlertAction *action){
                                               
                                               
                                               UITextField *alertTextField = alert.textFields.firstObject;
                                               
                                               NSLog(@"And the text is... %@!", alertTextField.text);
                                               
                                           }];

UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel
                                               handler: nil];


[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {

    textField.placeholder = @"Text here";

}];

[alert addAction:ok];
[alert addAction:cancel];

[self presentViewController:alert animated:YES completion:nil];

Previous answer:

Edit: - Please note: Currently, original question seems to be working as is.

To clarify:

The UIAlertController instance should hold the textField in its textFields array after calling the addTextFieldWithConfigurationHandler.

UIAlertController *alertController = ...// Create alert

// Assuming you called 'addTextFieldWithConfigurationHandler' on 'alertController'

UIAlertAction *action = [UIAlertAction actionWithTitle: ... handler:^(UIAlertAction * action) {
    
    // alertController.textFields should hold the alert's text fields.
}

If for some reason it is not, please shed more light (since this issue is still getting attention). It seems (by some of the comments) that some people had some issues with this, but did not provide information beyond 'it doesn't work'.


Original answer:

Your code looks fine, it should work.

Another way is to define a UITextField before UIAlertController *alert=...

UITextField *myTf;

Pass the textField from addTextFieldWithConfigurationHandler:

[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
            textField.placeholder = @"Enter the name of the recipe";
            textField.keyboardType = UIKeyboardTypeDefault;

            myTf = textField;
        }];

Then, in:

UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                               handler:^(UIAlertAction * action){...
//UITextField *temp = alert.textFields.firstObject;

// Get the text from your textField
NSString *temp = myTf.text;

-- EDIT

Original poster's code now works as is (tested under Xcode 7, iOS 9). Could have been a bug in previous version. Could be that in previous version the textField was held by a weak reference and got released unless another strong pointer was holding it.

bauerMusic
  • 5,470
  • 5
  • 38
  • 53
  • that works. still not sure why it didnt work the other way. Thanks for the help!! – Mark Worsnop Dec 31 '14 at 19:53
  • 1
    It does not work your way cause you lose the reference to your 'alert' after show this alert to the screen. You should keep a reference in a global variable of your ViewController. – Duyen-Hoa Aug 07 '15 at 09:07
  • 1
    @HoaParis First, it **does** work. Try it on a clean project. Currently it works exactly as the OP did it (bug in previous version?). Second, funny thing about blocks, they capture variables. – bauerMusic Dec 22 '15 at 07:48
  • It doesn't work (iOS9) . myTf.text doesn't return the updated text of the field. – Fab Jan 22 '16 at 21:03
  • @Fabrizio I just copy/paste this code in a new project and it's working here. Please see if you're doing something different in your project. What does "updated text" means? Sounds link somewhat of a different issue. And thanks for knocking down points. – bauerMusic Jan 28 '16 at 14:45
  • @bauerMusic 'true' exists in C which has "bool" while "YES" exists in Obj-C which uses "BOOL". presentViewController: animated: (BOOL)flag completion: calls for "BOOL". It's true that under the hood there is little to no difference between them but see this: http://stackoverflow.com/questions/28244584/objective-c-true-false-vs-true-false and this http://stackoverflow.com/questions/615702/is-there-a-difference-between-yes-no-true-false-and-true-false-in-objective-c – unom Aug 26 '16 at 13:04
  • @unmircea Thank! (Remove my older comment Bool vs bool as it was incorrect). – bauerMusic Aug 27 '16 at 18:00