如何解除UIAlertController和键盘同时?

我用UIAlertController创build了一个registry单,并使用方法addTextFieldWithConfigurationHandler添加一个文本字段。 但是有一个小问题。

当窗体出现时,键盘和模态以平滑的animation出现。 closures窗体时,模式首先消失, 然后键盘消失。 这使得键盘突然下降。

我怎样才能使模式和键盘优雅地消失?

 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 } 

提出和解雇

你可以设置你的视图控制器或其他对象作为你的UIAlertController( alert.transitioningDelegate )的转换委托,并为解散做一个自定义的animation。 代码示例:

 @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 

结果:

在这里输入图像说明

PS:我使用旧警报的过渡代表进行演示,因为我无法再现原始animation。 所以animatePresentation:方法从不使用。

我有完全相同的问题,并偶然发现解决scheme。 你可能不需要这个了,但为了像我这样的人,这里是答案:

迅速:

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

Objective-C的:

 - (BOOL)canBecomeFirstResponder { return true; } 

只需在处理警报的视图控制器中添加此代码即可。 只有迅速testing。

它非常简单。

如果您的UIAlertController委托出现在自己的 View Controller中。 那么你可以在Dismiss AlertController的代理方法中做到这一点。 你可以在你的UIAlertController对象中有[youtTextField resignFirstResponder] ,它有一个button来解除它。 (如确定或取消),所以你提交的KeyBoard将被解雇。

我没有尝试过,但它会工作。 但是您必须正确处理textField和Alert。

我假设UIAlertController的跳转是在按下键盘上的'return'之后解除。 如果是这样的话,我已经find了一种方法让警报和键盘顺利退出回收行动。

您将需要在类文件中声明UIAlertController

 @property (strong, nonatomic) UIAlertController *alertController; 

而且你还需要在viewController中使用UITextFieldDelegate。当将textField添加到UIAlertController时,这是你需要将它的代理设置为self的地方。 (弱,因为它在一个块内使用)

 @interface ViewController ()<UITextFieldDelegate> 

在拍卖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]; 

添加这个UITextField委托方法,一旦按下键盘上的返回button,就会触发它。 这意味着您可以在UIAlertController之前解除键盘开关,从而使其工作顺利。

 -(BOOL)textFieldShouldReturn:(UITextField *)textField{ [self.alertController dismissViewControllerAnimated:YES completion:nil]; return YES; } 

我已经testing过了,应该按照你的要求来工作。

谢谢,吉姆

  - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { [self.view endEditing:YES]; // or you can write [yourtextfield refignFirstResponder] [alertView dismissWithClickedButtonIndex:buttonIndex animated:TRUE]; } 
 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex==1) { [[alertView textFieldAtIndex:0] resignFirstResponder]; } else { [[alertView textFieldAtIndex:0] resignFirstResponder]; } } 

使用你的button索引(确定或取消button索引)

不需要做任何事情你只需要实现这么多的代码,它适用于我,不需要声明任何types的委托方法

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

}

Swizzle viewWillDisappear方法的UIAlertController,并执行resignFirstResponder相对应的文本字段或调用endEditing:在控制器的视图

我正在使用这个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() }