如何同时关闭UIAlertController和键盘?
我使用UIAlertController
创建了注册表单,并使用方法addTextFieldWithConfigurationHandler
添加文本字段。但是有一个小问题。如何同时关闭UIAlertController和键盘?
当表格显示出来时,键盘和模态会以平滑的动画出现。当关闭窗体时,模式首先消失和然后键盘消失。这会使键盘突然下降。
如何让模式和键盘优雅地消失?
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
)的委托,并创建自定义动画解雇。 代码示例:
@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
结果:
P.S:我使用的旧警报的过渡委托演示,因为我不能再现原始动画。所以animatePresentation:
方法从不使用。
它很简单。
如果您的UIAlertController
代表存在于自我视图控制器。那么您可以在其Dismiss AlertController的委托方法中执行此操作。你可以在你的UIAlertController对象中有[youtTextField resignFirstResponder]
,它有一个用于解除它的按钮。 (如确定或取消)所以你提交的KeyBoard将被解雇。
我没有尝试过,但它会工作。但是您必须正确处理textField和Alert。
对不起,我不明白这一点。你能提供一小段代码吗? – Randomblue 2015-04-11 04:27:12
@Randomblue在iOS中编写[textfield resignFirstResponder]时,它会从第一响应者辞职并隐藏键盘。因此,在alertdelegate方法中,您可以编写[textfield resignFirstResponder],这样键盘就会隐藏并且提醒也会消失。 – Bhoomi 2015-04-11 10:13:45
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self.view endEditing:YES];
// or you can write [yourtextfield refignFirstResponder]
[alertView dismissWithClickedButtonIndex:buttonIndex animated:TRUE];
}
您引用的这种委托方法适用于UIAlertView,UIAlertController不使用,因为它的解雇将在UIAction块内处理UIAlertController – 2015-04-11 10:35:39
我假设UIAlertController的跳跃是,如果在按下键盘上的'return'之后关闭它。如果是这样,我已经找到了一种方法让警报和键盘顺利退出回收行动。
您需要的类文件
@property (strong, nonatomic) UIAlertController *alertController;
内声明UIAlertController,你也将需要使用UITextFieldDelegate用的viewController 当添加文本框的UIAlertController这就是你需要设置委托给自己。 (使用weakSelf,因为它是一个块中)
@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委托方法一旦返回按钮被按下的时会触发键盘。这意味着您可以在UIAlertController在键盘解散之前解除操作,从而使其工作顺利进行。
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[self.alertController dismissViewControllerAnimated:YES completion:nil];
return YES;
}
我测试过了,应该按照您的要求工作。
感谢, 吉姆
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex==1) {
[[alertView textFieldAtIndex:0] resignFirstResponder];
} else {
[[alertView textFieldAtIndex:0] resignFirstResponder];
}
}
使用您的按钮指数(确定或取消按钮指数)
我有,你有完全相同的问题,并找到了解决办法偶然。你可能不需要这个了,但对于其他像我这样的缘故,这里的答案:
斯威夫特:
override func canBecomeFirstResponder() -> Bool {
return true
}
的Objective-C:
- (BOOL)canBecomeFirstResponder {
return true;
}
只需添加这处理警报的视图控制器中的代码。只在swift中进行测试。
没有必要做,你只需要实现这么多的代码的任何东西,它为我工作,无需声明任何形式的委托方法
}
调酒viewWillDisappear方法为UIAlertController,并在相应的文本字段或调用endEditing上执行resignFirstResponder:在控制器视图上
我正在使用此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()
}
您可以发布您用于创建UIAlertController和操作的代码。谢谢 – 2015-04-12 08:08:47
如果你可以共享一个测试应用程序,我愿意为你检查它。 – Shai 2015-04-12 08:38:10