I have created a signup form with a UIAlertController
and used the method addTextFieldWithConfigurationHandler
to add a text field. But there is a litt
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.
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
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];
}
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:
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.
- (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];
}
}
Use your button index (Ok or Cancel button index)