Prevent dismissal of UIAlertController












44















I am adding a UITextField to a UIAlertController, which appears as an AlertView. Before dismissing the UIAlertController, I want to validate the input of the UITextField. Based on the validation I want to dismiss the UIAlertController or not. But I have no clue how to prevent the dismissing action of the UIAlertController when a button is pressed. Has anyone solved this problem or any ideas where to start ? I went to google but no luck :/ Thanks!










share|improve this question





























    44















    I am adding a UITextField to a UIAlertController, which appears as an AlertView. Before dismissing the UIAlertController, I want to validate the input of the UITextField. Based on the validation I want to dismiss the UIAlertController or not. But I have no clue how to prevent the dismissing action of the UIAlertController when a button is pressed. Has anyone solved this problem or any ideas where to start ? I went to google but no luck :/ Thanks!










    share|improve this question



























      44












      44








      44


      13






      I am adding a UITextField to a UIAlertController, which appears as an AlertView. Before dismissing the UIAlertController, I want to validate the input of the UITextField. Based on the validation I want to dismiss the UIAlertController or not. But I have no clue how to prevent the dismissing action of the UIAlertController when a button is pressed. Has anyone solved this problem or any ideas where to start ? I went to google but no luck :/ Thanks!










      share|improve this question
















      I am adding a UITextField to a UIAlertController, which appears as an AlertView. Before dismissing the UIAlertController, I want to validate the input of the UITextField. Based on the validation I want to dismiss the UIAlertController or not. But I have no clue how to prevent the dismissing action of the UIAlertController when a button is pressed. Has anyone solved this problem or any ideas where to start ? I went to google but no luck :/ Thanks!







      swift uialertcontroller






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 7 '15 at 20:44









      Lyndsey Scott

      29.5k671113




      29.5k671113










      asked Sep 2 '14 at 16:21









      jona jürgenjona jürgen

      74431326




      74431326
























          4 Answers
          4






          active

          oldest

          votes


















          63














          You're correct: if the user can tap a button in your alert, the alert will be dismissed. So you want to prevent the user from tapping the button! It's all just a matter of disabling your UIAlertAction buttons. If an alert action is disabled, the user can't tap it to dismiss.



          To combine this with text field validation, use a text field delegate method or action method (configured in the text field's configuration handler when you create it) to enable/disable the UIAlertActions appropriately depending on what text has (or hasn't) been entered.



          Here's an example. We created the text field like this:



          alert.addTextFieldWithConfigurationHandler {
          (tf:UITextField!) in
          tf.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
          }


          We have a Cancel action and an OK action, and we brought the OK action into the world disabled:



          (alert.actions[1] as UIAlertAction).enabled = false


          Subsequently, the user can't tap OK unless there is some actual text in the text field:



          func textChanged(sender:AnyObject) {
          let tf = sender as UITextField
          var resp : UIResponder = tf
          while !(resp is UIAlertController) { resp = resp.nextResponder() }
          let alert = resp as UIAlertController
          (alert.actions[1] as UIAlertAction).enabled = (tf.text != "")
          }


          EDIT Here's the current (Swift 3.0.1 and later) version of the above code:



          alert.addTextField { tf in
          tf.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
          }


          and



          alert.actions[1].isEnabled = false


          and



          @objc func textChanged(_ sender: Any) {
          let tf = sender as! UITextField
          var resp : UIResponder! = tf
          while !(resp is UIAlertController) { resp = resp.next }
          let alert = resp as! UIAlertController
          alert.actions[1].isEnabled = (tf.text != "")
          }





          share|improve this answer


























          • Full example here: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…

            – matt
            Sep 2 '14 at 16:31











          • super!!! Many Thanks

            – Ulli H
            Aug 25 '15 at 18:23











          • Is there an Objective-C example of this laying around?

            – Adrian
            Sep 24 '15 at 12:04











          • Such a gorgeous, elegant answer. Thank you! I just used this on a Swift project.

            – Adrian
            Oct 15 '15 at 15:23













          • Thanks @AdrianB, you made my day.

            – matt
            Oct 15 '15 at 15:51



















          12














          I've simplified matt's answer without the view hierarcy traversing. This is holding the action itself as a weak variable instead. This is a fully working example:



          weak var actionToEnable : UIAlertAction?

          func showAlert()
          {
          let titleStr = "title"
          let messageStr = "message"

          let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)

          let placeholderStr = "placeholder"

          alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in
          textField.placeholder = placeholderStr
          textField.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
          })

          let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (_) -> Void in

          })

          let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (_) -> Void in
          let textfield = alert.textFields!.first!

          //Do what you want with the textfield!
          })

          alert.addAction(cancel)
          alert.addAction(action)

          self.actionToEnable = action
          action.enabled = false
          self.presentViewController(alert, animated: true, completion: nil)
          }

          func textChanged(sender:UITextField) {
          self.actionToEnable?.enabled = (sender.text! == "Validation")
          }





          share|improve this answer
























          • Thanks man! Works like a charm!

            – Murat Yasar
            Jan 5 '17 at 18:42











          • @ullstrm: Thanks it helped a lot.

            – Pawan
            Sep 11 '18 at 14:00



















          6














          Cribbing off of @Matt's answer, here's how I did the same thing in Obj-C



          - (BOOL)textField: (UITextField*) textField shouldChangeCharactersInRange: (NSRange) range replacementString: (NSString*)string
          {
          NSString *newString = [textField.text stringByReplacingCharactersInRange: range withString: string];

          // check string length
          NSInteger newLength = [newString length];
          BOOL okToChange = (newLength <= 16); // don't allow names longer than this

          if (okToChange)
          {
          // Find our Ok button
          UIResponder *responder = textField;
          Class uiacClass = [UIAlertController class];
          while (![responder isKindOfClass: uiacClass])
          {
          responder = [responder nextResponder];
          }
          UIAlertController *alert = (UIAlertController*) responder;
          UIAlertAction *okAction = [alert.actions objectAtIndex: 0];

          // Dis/enable Ok button based on same-name
          BOOL duplicateName = NO;
          // <check for duplicates, here>

          okAction.enabled = !duplicateName;
          }


          return (okToChange);
          }





          share|improve this answer































            2














            I realise that this is in Objectiv-C but it shows the principal. I will update this with a swift version later.



            You could also do the same using a block as the target.



            Add a property to your ViewController so that the block (closure for swift) has a strong reference



            @property (strong, nonatomic) id textValidationBlock;



            Then create the AlertViewController like so:



            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

            }];

            __weak typeof(self) weakSelf = self;
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [weakSelf doSomething];

            }];
            [alertController addAction:cancelAction];
            [alertController addAction:okAction];
            [alertController.actions lastObject].enabled = NO;
            self.textValidationBlock = [^{
            UITextField *textField = [alertController.textFields firstObject];
            if (something) {
            alertController.message = @"Warning message";
            [alertController.actions lastObject].enabled = NO;
            } else if (somethingElse) {
            alertController.message = @"Another warning message";
            [alertController.actions lastObject].enabled = NO;
            } else {
            //Validation passed
            alertController.message = @"";
            [alertController.actions lastObject].enabled = YES;
            }

            } copy];
            [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            textField.placeholder = @"placeholder here";
            [textField addTarget:weakSelf.textValidationBlock action:@selector(invoke) forControlEvents:UIControlEventEditingChanged];
            }];
            [self presentViewController:alertController animated:YES completion:nil];





            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25628000%2fprevent-dismissal-of-uialertcontroller%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              63














              You're correct: if the user can tap a button in your alert, the alert will be dismissed. So you want to prevent the user from tapping the button! It's all just a matter of disabling your UIAlertAction buttons. If an alert action is disabled, the user can't tap it to dismiss.



              To combine this with text field validation, use a text field delegate method or action method (configured in the text field's configuration handler when you create it) to enable/disable the UIAlertActions appropriately depending on what text has (or hasn't) been entered.



              Here's an example. We created the text field like this:



              alert.addTextFieldWithConfigurationHandler {
              (tf:UITextField!) in
              tf.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              }


              We have a Cancel action and an OK action, and we brought the OK action into the world disabled:



              (alert.actions[1] as UIAlertAction).enabled = false


              Subsequently, the user can't tap OK unless there is some actual text in the text field:



              func textChanged(sender:AnyObject) {
              let tf = sender as UITextField
              var resp : UIResponder = tf
              while !(resp is UIAlertController) { resp = resp.nextResponder() }
              let alert = resp as UIAlertController
              (alert.actions[1] as UIAlertAction).enabled = (tf.text != "")
              }


              EDIT Here's the current (Swift 3.0.1 and later) version of the above code:



              alert.addTextField { tf in
              tf.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
              }


              and



              alert.actions[1].isEnabled = false


              and



              @objc func textChanged(_ sender: Any) {
              let tf = sender as! UITextField
              var resp : UIResponder! = tf
              while !(resp is UIAlertController) { resp = resp.next }
              let alert = resp as! UIAlertController
              alert.actions[1].isEnabled = (tf.text != "")
              }





              share|improve this answer


























              • Full example here: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…

                – matt
                Sep 2 '14 at 16:31











              • super!!! Many Thanks

                – Ulli H
                Aug 25 '15 at 18:23











              • Is there an Objective-C example of this laying around?

                – Adrian
                Sep 24 '15 at 12:04











              • Such a gorgeous, elegant answer. Thank you! I just used this on a Swift project.

                – Adrian
                Oct 15 '15 at 15:23













              • Thanks @AdrianB, you made my day.

                – matt
                Oct 15 '15 at 15:51
















              63














              You're correct: if the user can tap a button in your alert, the alert will be dismissed. So you want to prevent the user from tapping the button! It's all just a matter of disabling your UIAlertAction buttons. If an alert action is disabled, the user can't tap it to dismiss.



              To combine this with text field validation, use a text field delegate method or action method (configured in the text field's configuration handler when you create it) to enable/disable the UIAlertActions appropriately depending on what text has (or hasn't) been entered.



              Here's an example. We created the text field like this:



              alert.addTextFieldWithConfigurationHandler {
              (tf:UITextField!) in
              tf.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              }


              We have a Cancel action and an OK action, and we brought the OK action into the world disabled:



              (alert.actions[1] as UIAlertAction).enabled = false


              Subsequently, the user can't tap OK unless there is some actual text in the text field:



              func textChanged(sender:AnyObject) {
              let tf = sender as UITextField
              var resp : UIResponder = tf
              while !(resp is UIAlertController) { resp = resp.nextResponder() }
              let alert = resp as UIAlertController
              (alert.actions[1] as UIAlertAction).enabled = (tf.text != "")
              }


              EDIT Here's the current (Swift 3.0.1 and later) version of the above code:



              alert.addTextField { tf in
              tf.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
              }


              and



              alert.actions[1].isEnabled = false


              and



              @objc func textChanged(_ sender: Any) {
              let tf = sender as! UITextField
              var resp : UIResponder! = tf
              while !(resp is UIAlertController) { resp = resp.next }
              let alert = resp as! UIAlertController
              alert.actions[1].isEnabled = (tf.text != "")
              }





              share|improve this answer


























              • Full example here: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…

                – matt
                Sep 2 '14 at 16:31











              • super!!! Many Thanks

                – Ulli H
                Aug 25 '15 at 18:23











              • Is there an Objective-C example of this laying around?

                – Adrian
                Sep 24 '15 at 12:04











              • Such a gorgeous, elegant answer. Thank you! I just used this on a Swift project.

                – Adrian
                Oct 15 '15 at 15:23













              • Thanks @AdrianB, you made my day.

                – matt
                Oct 15 '15 at 15:51














              63












              63








              63







              You're correct: if the user can tap a button in your alert, the alert will be dismissed. So you want to prevent the user from tapping the button! It's all just a matter of disabling your UIAlertAction buttons. If an alert action is disabled, the user can't tap it to dismiss.



              To combine this with text field validation, use a text field delegate method or action method (configured in the text field's configuration handler when you create it) to enable/disable the UIAlertActions appropriately depending on what text has (or hasn't) been entered.



              Here's an example. We created the text field like this:



              alert.addTextFieldWithConfigurationHandler {
              (tf:UITextField!) in
              tf.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              }


              We have a Cancel action and an OK action, and we brought the OK action into the world disabled:



              (alert.actions[1] as UIAlertAction).enabled = false


              Subsequently, the user can't tap OK unless there is some actual text in the text field:



              func textChanged(sender:AnyObject) {
              let tf = sender as UITextField
              var resp : UIResponder = tf
              while !(resp is UIAlertController) { resp = resp.nextResponder() }
              let alert = resp as UIAlertController
              (alert.actions[1] as UIAlertAction).enabled = (tf.text != "")
              }


              EDIT Here's the current (Swift 3.0.1 and later) version of the above code:



              alert.addTextField { tf in
              tf.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
              }


              and



              alert.actions[1].isEnabled = false


              and



              @objc func textChanged(_ sender: Any) {
              let tf = sender as! UITextField
              var resp : UIResponder! = tf
              while !(resp is UIAlertController) { resp = resp.next }
              let alert = resp as! UIAlertController
              alert.actions[1].isEnabled = (tf.text != "")
              }





              share|improve this answer















              You're correct: if the user can tap a button in your alert, the alert will be dismissed. So you want to prevent the user from tapping the button! It's all just a matter of disabling your UIAlertAction buttons. If an alert action is disabled, the user can't tap it to dismiss.



              To combine this with text field validation, use a text field delegate method or action method (configured in the text field's configuration handler when you create it) to enable/disable the UIAlertActions appropriately depending on what text has (or hasn't) been entered.



              Here's an example. We created the text field like this:



              alert.addTextFieldWithConfigurationHandler {
              (tf:UITextField!) in
              tf.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              }


              We have a Cancel action and an OK action, and we brought the OK action into the world disabled:



              (alert.actions[1] as UIAlertAction).enabled = false


              Subsequently, the user can't tap OK unless there is some actual text in the text field:



              func textChanged(sender:AnyObject) {
              let tf = sender as UITextField
              var resp : UIResponder = tf
              while !(resp is UIAlertController) { resp = resp.nextResponder() }
              let alert = resp as UIAlertController
              (alert.actions[1] as UIAlertAction).enabled = (tf.text != "")
              }


              EDIT Here's the current (Swift 3.0.1 and later) version of the above code:



              alert.addTextField { tf in
              tf.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
              }


              and



              alert.actions[1].isEnabled = false


              and



              @objc func textChanged(_ sender: Any) {
              let tf = sender as! UITextField
              var resp : UIResponder! = tf
              while !(resp is UIAlertController) { resp = resp.next }
              let alert = resp as! UIAlertController
              alert.actions[1].isEnabled = (tf.text != "")
              }






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 23 '18 at 16:00

























              answered Sep 2 '14 at 16:25









              mattmatt

              326k46527727




              326k46527727













              • Full example here: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…

                – matt
                Sep 2 '14 at 16:31











              • super!!! Many Thanks

                – Ulli H
                Aug 25 '15 at 18:23











              • Is there an Objective-C example of this laying around?

                – Adrian
                Sep 24 '15 at 12:04











              • Such a gorgeous, elegant answer. Thank you! I just used this on a Swift project.

                – Adrian
                Oct 15 '15 at 15:23













              • Thanks @AdrianB, you made my day.

                – matt
                Oct 15 '15 at 15:51



















              • Full example here: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…

                – matt
                Sep 2 '14 at 16:31











              • super!!! Many Thanks

                – Ulli H
                Aug 25 '15 at 18:23











              • Is there an Objective-C example of this laying around?

                – Adrian
                Sep 24 '15 at 12:04











              • Such a gorgeous, elegant answer. Thank you! I just used this on a Swift project.

                – Adrian
                Oct 15 '15 at 15:23













              • Thanks @AdrianB, you made my day.

                – matt
                Oct 15 '15 at 15:51

















              Full example here: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…

              – matt
              Sep 2 '14 at 16:31





              Full example here: github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…

              – matt
              Sep 2 '14 at 16:31













              super!!! Many Thanks

              – Ulli H
              Aug 25 '15 at 18:23





              super!!! Many Thanks

              – Ulli H
              Aug 25 '15 at 18:23













              Is there an Objective-C example of this laying around?

              – Adrian
              Sep 24 '15 at 12:04





              Is there an Objective-C example of this laying around?

              – Adrian
              Sep 24 '15 at 12:04













              Such a gorgeous, elegant answer. Thank you! I just used this on a Swift project.

              – Adrian
              Oct 15 '15 at 15:23







              Such a gorgeous, elegant answer. Thank you! I just used this on a Swift project.

              – Adrian
              Oct 15 '15 at 15:23















              Thanks @AdrianB, you made my day.

              – matt
              Oct 15 '15 at 15:51





              Thanks @AdrianB, you made my day.

              – matt
              Oct 15 '15 at 15:51













              12














              I've simplified matt's answer without the view hierarcy traversing. This is holding the action itself as a weak variable instead. This is a fully working example:



              weak var actionToEnable : UIAlertAction?

              func showAlert()
              {
              let titleStr = "title"
              let messageStr = "message"

              let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)

              let placeholderStr = "placeholder"

              alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in
              textField.placeholder = placeholderStr
              textField.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              })

              let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (_) -> Void in

              })

              let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (_) -> Void in
              let textfield = alert.textFields!.first!

              //Do what you want with the textfield!
              })

              alert.addAction(cancel)
              alert.addAction(action)

              self.actionToEnable = action
              action.enabled = false
              self.presentViewController(alert, animated: true, completion: nil)
              }

              func textChanged(sender:UITextField) {
              self.actionToEnable?.enabled = (sender.text! == "Validation")
              }





              share|improve this answer
























              • Thanks man! Works like a charm!

                – Murat Yasar
                Jan 5 '17 at 18:42











              • @ullstrm: Thanks it helped a lot.

                – Pawan
                Sep 11 '18 at 14:00
















              12














              I've simplified matt's answer without the view hierarcy traversing. This is holding the action itself as a weak variable instead. This is a fully working example:



              weak var actionToEnable : UIAlertAction?

              func showAlert()
              {
              let titleStr = "title"
              let messageStr = "message"

              let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)

              let placeholderStr = "placeholder"

              alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in
              textField.placeholder = placeholderStr
              textField.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              })

              let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (_) -> Void in

              })

              let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (_) -> Void in
              let textfield = alert.textFields!.first!

              //Do what you want with the textfield!
              })

              alert.addAction(cancel)
              alert.addAction(action)

              self.actionToEnable = action
              action.enabled = false
              self.presentViewController(alert, animated: true, completion: nil)
              }

              func textChanged(sender:UITextField) {
              self.actionToEnable?.enabled = (sender.text! == "Validation")
              }





              share|improve this answer
























              • Thanks man! Works like a charm!

                – Murat Yasar
                Jan 5 '17 at 18:42











              • @ullstrm: Thanks it helped a lot.

                – Pawan
                Sep 11 '18 at 14:00














              12












              12








              12







              I've simplified matt's answer without the view hierarcy traversing. This is holding the action itself as a weak variable instead. This is a fully working example:



              weak var actionToEnable : UIAlertAction?

              func showAlert()
              {
              let titleStr = "title"
              let messageStr = "message"

              let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)

              let placeholderStr = "placeholder"

              alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in
              textField.placeholder = placeholderStr
              textField.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              })

              let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (_) -> Void in

              })

              let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (_) -> Void in
              let textfield = alert.textFields!.first!

              //Do what you want with the textfield!
              })

              alert.addAction(cancel)
              alert.addAction(action)

              self.actionToEnable = action
              action.enabled = false
              self.presentViewController(alert, animated: true, completion: nil)
              }

              func textChanged(sender:UITextField) {
              self.actionToEnable?.enabled = (sender.text! == "Validation")
              }





              share|improve this answer













              I've simplified matt's answer without the view hierarcy traversing. This is holding the action itself as a weak variable instead. This is a fully working example:



              weak var actionToEnable : UIAlertAction?

              func showAlert()
              {
              let titleStr = "title"
              let messageStr = "message"

              let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)

              let placeholderStr = "placeholder"

              alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in
              textField.placeholder = placeholderStr
              textField.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
              })

              let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (_) -> Void in

              })

              let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (_) -> Void in
              let textfield = alert.textFields!.first!

              //Do what you want with the textfield!
              })

              alert.addAction(cancel)
              alert.addAction(action)

              self.actionToEnable = action
              action.enabled = false
              self.presentViewController(alert, animated: true, completion: nil)
              }

              func textChanged(sender:UITextField) {
              self.actionToEnable?.enabled = (sender.text! == "Validation")
              }






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Mar 19 '16 at 8:58









              ullstrmullstrm

              5,76644073




              5,76644073













              • Thanks man! Works like a charm!

                – Murat Yasar
                Jan 5 '17 at 18:42











              • @ullstrm: Thanks it helped a lot.

                – Pawan
                Sep 11 '18 at 14:00



















              • Thanks man! Works like a charm!

                – Murat Yasar
                Jan 5 '17 at 18:42











              • @ullstrm: Thanks it helped a lot.

                – Pawan
                Sep 11 '18 at 14:00

















              Thanks man! Works like a charm!

              – Murat Yasar
              Jan 5 '17 at 18:42





              Thanks man! Works like a charm!

              – Murat Yasar
              Jan 5 '17 at 18:42













              @ullstrm: Thanks it helped a lot.

              – Pawan
              Sep 11 '18 at 14:00





              @ullstrm: Thanks it helped a lot.

              – Pawan
              Sep 11 '18 at 14:00











              6














              Cribbing off of @Matt's answer, here's how I did the same thing in Obj-C



              - (BOOL)textField: (UITextField*) textField shouldChangeCharactersInRange: (NSRange) range replacementString: (NSString*)string
              {
              NSString *newString = [textField.text stringByReplacingCharactersInRange: range withString: string];

              // check string length
              NSInteger newLength = [newString length];
              BOOL okToChange = (newLength <= 16); // don't allow names longer than this

              if (okToChange)
              {
              // Find our Ok button
              UIResponder *responder = textField;
              Class uiacClass = [UIAlertController class];
              while (![responder isKindOfClass: uiacClass])
              {
              responder = [responder nextResponder];
              }
              UIAlertController *alert = (UIAlertController*) responder;
              UIAlertAction *okAction = [alert.actions objectAtIndex: 0];

              // Dis/enable Ok button based on same-name
              BOOL duplicateName = NO;
              // <check for duplicates, here>

              okAction.enabled = !duplicateName;
              }


              return (okToChange);
              }





              share|improve this answer




























                6














                Cribbing off of @Matt's answer, here's how I did the same thing in Obj-C



                - (BOOL)textField: (UITextField*) textField shouldChangeCharactersInRange: (NSRange) range replacementString: (NSString*)string
                {
                NSString *newString = [textField.text stringByReplacingCharactersInRange: range withString: string];

                // check string length
                NSInteger newLength = [newString length];
                BOOL okToChange = (newLength <= 16); // don't allow names longer than this

                if (okToChange)
                {
                // Find our Ok button
                UIResponder *responder = textField;
                Class uiacClass = [UIAlertController class];
                while (![responder isKindOfClass: uiacClass])
                {
                responder = [responder nextResponder];
                }
                UIAlertController *alert = (UIAlertController*) responder;
                UIAlertAction *okAction = [alert.actions objectAtIndex: 0];

                // Dis/enable Ok button based on same-name
                BOOL duplicateName = NO;
                // <check for duplicates, here>

                okAction.enabled = !duplicateName;
                }


                return (okToChange);
                }





                share|improve this answer


























                  6












                  6








                  6







                  Cribbing off of @Matt's answer, here's how I did the same thing in Obj-C



                  - (BOOL)textField: (UITextField*) textField shouldChangeCharactersInRange: (NSRange) range replacementString: (NSString*)string
                  {
                  NSString *newString = [textField.text stringByReplacingCharactersInRange: range withString: string];

                  // check string length
                  NSInteger newLength = [newString length];
                  BOOL okToChange = (newLength <= 16); // don't allow names longer than this

                  if (okToChange)
                  {
                  // Find our Ok button
                  UIResponder *responder = textField;
                  Class uiacClass = [UIAlertController class];
                  while (![responder isKindOfClass: uiacClass])
                  {
                  responder = [responder nextResponder];
                  }
                  UIAlertController *alert = (UIAlertController*) responder;
                  UIAlertAction *okAction = [alert.actions objectAtIndex: 0];

                  // Dis/enable Ok button based on same-name
                  BOOL duplicateName = NO;
                  // <check for duplicates, here>

                  okAction.enabled = !duplicateName;
                  }


                  return (okToChange);
                  }





                  share|improve this answer













                  Cribbing off of @Matt's answer, here's how I did the same thing in Obj-C



                  - (BOOL)textField: (UITextField*) textField shouldChangeCharactersInRange: (NSRange) range replacementString: (NSString*)string
                  {
                  NSString *newString = [textField.text stringByReplacingCharactersInRange: range withString: string];

                  // check string length
                  NSInteger newLength = [newString length];
                  BOOL okToChange = (newLength <= 16); // don't allow names longer than this

                  if (okToChange)
                  {
                  // Find our Ok button
                  UIResponder *responder = textField;
                  Class uiacClass = [UIAlertController class];
                  while (![responder isKindOfClass: uiacClass])
                  {
                  responder = [responder nextResponder];
                  }
                  UIAlertController *alert = (UIAlertController*) responder;
                  UIAlertAction *okAction = [alert.actions objectAtIndex: 0];

                  // Dis/enable Ok button based on same-name
                  BOOL duplicateName = NO;
                  // <check for duplicates, here>

                  okAction.enabled = !duplicateName;
                  }


                  return (okToChange);
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 3 '15 at 1:02









                  OlieOlie

                  18.2k1785126




                  18.2k1785126























                      2














                      I realise that this is in Objectiv-C but it shows the principal. I will update this with a swift version later.



                      You could also do the same using a block as the target.



                      Add a property to your ViewController so that the block (closure for swift) has a strong reference



                      @property (strong, nonatomic) id textValidationBlock;



                      Then create the AlertViewController like so:



                      UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
                      UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

                      }];

                      __weak typeof(self) weakSelf = self;
                      UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                      [weakSelf doSomething];

                      }];
                      [alertController addAction:cancelAction];
                      [alertController addAction:okAction];
                      [alertController.actions lastObject].enabled = NO;
                      self.textValidationBlock = [^{
                      UITextField *textField = [alertController.textFields firstObject];
                      if (something) {
                      alertController.message = @"Warning message";
                      [alertController.actions lastObject].enabled = NO;
                      } else if (somethingElse) {
                      alertController.message = @"Another warning message";
                      [alertController.actions lastObject].enabled = NO;
                      } else {
                      //Validation passed
                      alertController.message = @"";
                      [alertController.actions lastObject].enabled = YES;
                      }

                      } copy];
                      [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
                      textField.placeholder = @"placeholder here";
                      [textField addTarget:weakSelf.textValidationBlock action:@selector(invoke) forControlEvents:UIControlEventEditingChanged];
                      }];
                      [self presentViewController:alertController animated:YES completion:nil];





                      share|improve this answer






























                        2














                        I realise that this is in Objectiv-C but it shows the principal. I will update this with a swift version later.



                        You could also do the same using a block as the target.



                        Add a property to your ViewController so that the block (closure for swift) has a strong reference



                        @property (strong, nonatomic) id textValidationBlock;



                        Then create the AlertViewController like so:



                        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
                        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

                        }];

                        __weak typeof(self) weakSelf = self;
                        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                        [weakSelf doSomething];

                        }];
                        [alertController addAction:cancelAction];
                        [alertController addAction:okAction];
                        [alertController.actions lastObject].enabled = NO;
                        self.textValidationBlock = [^{
                        UITextField *textField = [alertController.textFields firstObject];
                        if (something) {
                        alertController.message = @"Warning message";
                        [alertController.actions lastObject].enabled = NO;
                        } else if (somethingElse) {
                        alertController.message = @"Another warning message";
                        [alertController.actions lastObject].enabled = NO;
                        } else {
                        //Validation passed
                        alertController.message = @"";
                        [alertController.actions lastObject].enabled = YES;
                        }

                        } copy];
                        [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
                        textField.placeholder = @"placeholder here";
                        [textField addTarget:weakSelf.textValidationBlock action:@selector(invoke) forControlEvents:UIControlEventEditingChanged];
                        }];
                        [self presentViewController:alertController animated:YES completion:nil];





                        share|improve this answer




























                          2












                          2








                          2







                          I realise that this is in Objectiv-C but it shows the principal. I will update this with a swift version later.



                          You could also do the same using a block as the target.



                          Add a property to your ViewController so that the block (closure for swift) has a strong reference



                          @property (strong, nonatomic) id textValidationBlock;



                          Then create the AlertViewController like so:



                          UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
                          UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

                          }];

                          __weak typeof(self) weakSelf = self;
                          UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                          [weakSelf doSomething];

                          }];
                          [alertController addAction:cancelAction];
                          [alertController addAction:okAction];
                          [alertController.actions lastObject].enabled = NO;
                          self.textValidationBlock = [^{
                          UITextField *textField = [alertController.textFields firstObject];
                          if (something) {
                          alertController.message = @"Warning message";
                          [alertController.actions lastObject].enabled = NO;
                          } else if (somethingElse) {
                          alertController.message = @"Another warning message";
                          [alertController.actions lastObject].enabled = NO;
                          } else {
                          //Validation passed
                          alertController.message = @"";
                          [alertController.actions lastObject].enabled = YES;
                          }

                          } copy];
                          [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
                          textField.placeholder = @"placeholder here";
                          [textField addTarget:weakSelf.textValidationBlock action:@selector(invoke) forControlEvents:UIControlEventEditingChanged];
                          }];
                          [self presentViewController:alertController animated:YES completion:nil];





                          share|improve this answer















                          I realise that this is in Objectiv-C but it shows the principal. I will update this with a swift version later.



                          You could also do the same using a block as the target.



                          Add a property to your ViewController so that the block (closure for swift) has a strong reference



                          @property (strong, nonatomic) id textValidationBlock;



                          Then create the AlertViewController like so:



                          UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
                          UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

                          }];

                          __weak typeof(self) weakSelf = self;
                          UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                          [weakSelf doSomething];

                          }];
                          [alertController addAction:cancelAction];
                          [alertController addAction:okAction];
                          [alertController.actions lastObject].enabled = NO;
                          self.textValidationBlock = [^{
                          UITextField *textField = [alertController.textFields firstObject];
                          if (something) {
                          alertController.message = @"Warning message";
                          [alertController.actions lastObject].enabled = NO;
                          } else if (somethingElse) {
                          alertController.message = @"Another warning message";
                          [alertController.actions lastObject].enabled = NO;
                          } else {
                          //Validation passed
                          alertController.message = @"";
                          [alertController.actions lastObject].enabled = YES;
                          }

                          } copy];
                          [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
                          textField.placeholder = @"placeholder here";
                          [textField addTarget:weakSelf.textValidationBlock action:@selector(invoke) forControlEvents:UIControlEventEditingChanged];
                          }];
                          [self presentViewController:alertController animated:YES completion:nil];






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Jul 22 '16 at 14:50

























                          answered Jul 22 '16 at 14:42









                          Swinny89Swinny89

                          5,49222347




                          5,49222347






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25628000%2fprevent-dismissal-of-uialertcontroller%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              這個網誌中的熱門文章

                              Xamarin.form Move up view when keyboard appear

                              Post-Redirect-Get with Spring WebFlux and Thymeleaf

                              Anylogic : not able to use stopDelay()