How to dismiss an UIAlertController and the keyboa

2019-03-15 07:09发布

I have created a signup form with a UIAlertController and used the method addTextFieldWithConfigurationHandler to add a text field. But there is a little problem.

When the form shows up, the keyboard and modal appear with a smooth animation. When closing the form, the modal disappears first, and then the keyboard disappears. This makes the keyboard make a sudden downward fall.

How can I make the modal and keyboard graciously disappear?

lazy var alertController: UIAlertController = { [weak self] in
    let alert = UIAlertController(title: "Alert", message: "This is a demo alert", preferredStyle: .Alert)
    alert.addTextFieldWithConfigurationHandler { textField in
        textField.delegate = self
    }
    alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
    return alert
}()

@IBAction func alert() {
    presentViewController(alertController, animated: true, completion: nil)
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    alertController.dismissViewControllerAnimated(true, completion: nil)
    return true
}

presenting and dismissing

8条回答
【Aperson】
2楼-- · 2019-03-15 07:36

I assume the jumping down of the UIAlertController is if it dismisses after you press 'return' on the keyboard. If so, I have found a way for the Alert and keyboard to dismiss smoothly from a return action.

You will need declare the UIAlertController within the class file

@property (strong, nonatomic) UIAlertController *alertController;

And you will also need to use the UITextFieldDelegate with the viewController When adding the textField to the UIAlertController this is where you will need to set the delegate of it to self. (weakSelf used as it is within a block)

@interface ViewController ()<UITextFieldDelegate>

Within the method you are auctioning the UIAlertController -

   self.alertController = [UIAlertController alertControllerWithTitle:@"Alert" message:@"This is the message" preferredStyle:UIAlertControllerStyleAlert];


   __weak typeof(self) weakSelf = self;

   [self.alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
       textField.delegate = weakSelf;
   }];

   [self presentViewController:self.alertController animated:YES completion:nil];

Add this UITextField delegate method which will fire once the return button has been pressed on the keyboard. This means you can action for the UIAlertController to dismiss just prior to the keyboard dismissing, thus it makes it all work smoothly.

-(BOOL)textFieldShouldReturn:(UITextField *)textField{

   [self.alertController dismissViewControllerAnimated:YES completion:nil];

   return YES;

}

I've tested this and should work exactly the way you require.

Thanks, Jim

查看更多
smile是对你的礼貌
3楼-- · 2019-03-15 07:39

I had the exact same problem you had and found the solution incidentally. You probably don't need this anymore, but for the sake of others like me, here is the answer:

Swift:

override func canBecomeFirstResponder() -> Bool {
    return true
}

Objective-C:

- (BOOL)canBecomeFirstResponder {
    return true;
}

Just add this code in the view controller handling the alert. Only tested in swift.

查看更多
成全新的幸福
4楼-- · 2019-03-15 07:43
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

   { 

if (buttonIndex==1) {

        [[alertView textFieldAtIndex:0] resignFirstResponder];

        } else {

            [[alertView textFieldAtIndex:0] resignFirstResponder];

        }
    }

Use your button index (Ok or Cancel button index)

查看更多
时光不老,我们不散
5楼-- · 2019-03-15 07:47
   - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

   { 
       [self.view endEditing:YES];
      // or you can write [yourtextfield refignFirstResponder]
       [alertView dismissWithClickedButtonIndex:buttonIndex animated:TRUE];
   }
查看更多
Ridiculous、
6楼-- · 2019-03-15 07:50

no need to do any thing you just have to implement this much of code, it works for me, no need to declare any kind of delegate methods

- (void)showAlert {
self.alertController = [UIAlertController alertControllerWithTitle:@"Alert"
                                                           message:@"Enter Name:"
                                                    preferredStyle:UIAlertControllerStyleAlert];
[self.alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {

}];
[self.alertController addAction:[UIAlertAction actionWithTitle:@"Ok"
                                                         style:UIAlertActionStyleCancel
                                                       handler:nil]];
[self presentViewController:self.alertController animated:YES completion:nil];

}

查看更多
在下西门庆
7楼-- · 2019-03-15 07:51

Swizzle viewWillDisappear method for UIAlertController, and perform resignFirstResponder on correspodent text field or call endEditing: on controller's view

I am using for this ReactiveCocoa:

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

        alert.addTextFieldWithConfigurationHandler {
           textField in
        }

        let textField = alert.textFields!.first!

        alert.rac_signalForSelector(#selector(viewWillDisappear(_:)))
             .subscribeNext {
                 _ in
                 textField.resignFirstResponder()
             }
查看更多
登录 后发表回答