How to dismiss an UIAlertController and the keyboard simultaneously?

后端 未结 8 1254
离开以前
离开以前 2021-02-05 13:04

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

相关标签:
8条回答
  • 2021-02-05 13:16

    Its pretty simple.

    if your UIAlertController delegate are present in self View Controller. then you can do it in its delegate method for Dismiss AlertController. You can [youtTextField resignFirstResponder] in your UIAlertController object which have a button for dismiss it. (like OK or Cancel) so your presented KeyBoard will be dismissed.

    I didn't tried it but It will work. but you have to handle textField and Alert correctly.

    0 讨论(0)
  • 2021-02-05 13:21

    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

    0 讨论(0)
  • 2021-02-05 13:22

    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];
    

    }

    0 讨论(0)
  • 2021-02-05 13:24

    You can set your view controller or other object as transitioning delegate of your UIAlertController (alert.transitioningDelegate) and make a custom animation for dismissing. Code sample:

    @interface ViewController () <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning, UITextFieldDelegate>
    @property (assign, nonatomic) NSTimeInterval keyboardAnimationDuration;
    @property (assign, nonatomic) CGFloat keyboardHeight;
    @property (nonatomic, strong) UIAlertController *alertController;
    @property (nonatomic,strong) id <UIViewControllerTransitioningDelegate> transitioningDelegateForAlertController;
    @end
    
    @implementation ViewController
    
    - (void)dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self subscribeForKeyboardNotification];
    }
    
    #pragma mark - Keyboard notifications
    
    - (void)subscribeForKeyboardNotification {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillAppear:)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];
    }
    
    - (void)keyboardWillAppear:(NSNotification *)notification {
        self.keyboardAnimationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
        self.keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
    }
    
    #pragma mark - IBAction
    
    - (IBAction)showAlertButtonPressed:(id)sender {
        [self showAlert];
    }
    
    - (void)showAlert {
        self.alertController = [UIAlertController alertControllerWithTitle:@"Alert"
                                                                                 message:@"This is a demo alert"
                                                                          preferredStyle:UIAlertControllerStyleAlert];
        __weak typeof(self) weakSelf = self;
        [self.alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
            textField.delegate = weakSelf;
        }];
        self.transitioningDelegateForAlertController = self.alertController.transitioningDelegate;
        self.alertController.transitioningDelegate = self;
        [self.alertController addAction:[UIAlertAction actionWithTitle:@"Ok"
                                                            style:UIAlertActionStyleCancel
                                                          handler:nil]];
        [self presentViewController:self.alertController animated:YES completion:nil];
    }
    
    #pragma mark - UITextFieldDelegate
    
    - (BOOL)textFieldShouldReturn:(UITextField *)textField {
        [self.alertController dismissViewControllerAnimated:YES completion:nil];
        return YES;
    }
    
    #pragma mark - UIViewControllerTransitioningDelegate
    
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                       presentingController:(UIViewController *)presenting
                                                                           sourceController:(UIViewController *)source {
        return [self.transitioningDelegateForAlertController animationControllerForPresentedController:presented
                                                                              presentingController:presenting
                                                                                  sourceController:source];
    }
    
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
        return self;
    }
    
    #pragma mark - UIViewControllerAnimatedTransitioning
    
    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
        return self.keyboardAnimationDuration ?: 0.5;
    }
    
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
        UIViewController *destination = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        if ([destination isBeingPresented])
            [self animatePresentation:transitionContext];
        else
            [self animateDismissal:transitionContext];
    }
    
    - (void)animatePresentation:(id <UIViewControllerContextTransitioning>)transitionContext {
        NSTimeInterval transitionDuration = [self transitionDuration:transitionContext];
        UIViewController *fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController *toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        UIView *container = transitionContext.containerView;
        fromController.view.frame = container.bounds;
        toController.view.frame = container.bounds;
        toController.view.alpha = 0.0f;
        [container addSubview:toController.view];
        [fromController beginAppearanceTransition:NO animated:YES];
        [UIView animateWithDuration:transitionDuration
                         animations:^{
                             toController.view.alpha = 1.0;
                         }
                         completion:^(BOOL finished) {
                             [fromController endAppearanceTransition];
                             [transitionContext completeTransition:YES];
                         }];
    }
    
    - (void)animateDismissal:(id <UIViewControllerContextTransitioning>)transitionContext {
        NSTimeInterval transitionDuration = [self transitionDuration:transitionContext];
        UIViewController *fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController *toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
        [toController beginAppearanceTransition:YES animated:YES];
        [UIView animateWithDuration:transitionDuration
                         animations:^{
                             fromController.view.alpha = 0.0;
                             [fromController.view endEditing:YES];
                             CGRect frame = fromController.view.frame;
                             frame.origin.y += self.keyboardHeight / 2;
                             fromController.view.frame = frame;
                         }
                         completion:^(BOOL finished) {
                             [toController endAppearanceTransition];
                             [transitionContext completeTransition:YES];
                         }];
    }
    
    @end
    

    Result:

    enter image description here

    P.S.: I used old alert's transitioning delegate for presentation because I can't reproduce an original animation. So animatePresentation: method is never used.

    0 讨论(0)
  • 2021-02-05 13:27
       - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    
       { 
           [self.view endEditing:YES];
          // or you can write [yourtextfield refignFirstResponder]
           [alertView dismissWithClickedButtonIndex:buttonIndex animated:TRUE];
       }
    
    0 讨论(0)
  • 2021-02-05 13:30
    - (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)

    0 讨论(0)
提交回复
热议问题