![](/img/trans.png)
[英]UIAlertController with textfield: how dismiss keyboard works?
[英]How to dismiss an UIAlertController and the keyboard simultaneously?
我已经使用UIAlertController
创建了一个注册表单,并使用addTextFieldWithConfigurationHandler
方法添加了一个文本字段。 但是有一点问题。
当表单出现时,键盘和模态会以平滑的动画显示。 关闭表单时,模态首先消失, 然后键盘消失。 这使键盘突然下降。
如何使模态和键盘优雅地消失?
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
结果:
PS:我使用旧警报转换代表进行演示,因为我无法重现原始动画。 所以animatePresentation:
方法从未使用过。
我遇到了完全相同的问题并偶然找到了解决方案。 你可能不再需要这个,但为了像我这样的其他人,这里是答案:
迅速:
override func canBecomeFirstResponder() -> Bool {
return true
}
Objective-C的:
- (BOOL)canBecomeFirstResponder {
return true;
}
只需在处理警报的视图控制器中添加此代码即可。 只在swift中测试过。
它非常简单。
如果您的UIAlertController
委托存在于自身视图控制器中。 那么你可以在它的Dismiss AlertController的委托方法中做到这一点。 您可以在UIAlertController对象中使用[youtTextField resignFirstResponder]
,该对象具有用于关闭它的按钮。 (如“确定”或“取消”),因此您呈现的KeyBoard将被解雇。
我没试过但它会起作用。 但你必须正确处理textField和Alert。
我假设UIAlertController的跳跃是在你按下键盘上的'return'之后它解散了。 如果是这样,我找到了一种让Alert和键盘顺利解除返回动作的方法。
您需要在类文件中声明UIAlertController
@property (strong, nonatomic) UIAlertController *alertController;
并且您还需要将UITextFieldDelegate与viewController一起使用将textField添加到UIAlertController时,您需要将它的委托设置为self。 (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
{
[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];
}
}
使用按钮索引(确定或取消按钮索引)
没有必要做任何你只需要实现这么多代码的东西,它对我有用,不需要声明任何种类的委托方法
- (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];
}
用于UIAlertController的Swizzle viewWillDisappear方法,并在correspodent文本字段上执行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()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.