3

While working on project, i came across this problem.

One of the controller implement thekeyboardWillShow & keyboardWillHide (Standard code from Apple Managing the Keyboard). On Background tap,UIAlertView Appears(based on some validation), there is only one button in UIAlertView that simply close the UIAlertView.

Problem occurs here, on close of UIAlertView, keyboardWillShow & keyboardWillHide called again.

Below is the code i am having problem,

#import "ViewController.h"

@interface ViewController () <UITextFieldDelegate>
{
   int timeCalledShow;
   int timeCalledHide;
}
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
- (IBAction)backgroundTapped:(id)sender;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardDidHideNotification
                                           object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {

    timeCalledShow+=1;
    NSLog(@"show Time Called %d", timeCalledShow);
    CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets;
    if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) {
        contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.height), 0.0);
} else {
        contentInsets = UIEdgeInsetsMake(0.0, 0.0, (keyboardSize.width), 0.0);
}
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}

- (void)keyboardWillHide:(NSNotification *)notification {
    timeCalledHide+=1;
    NSLog(@"Hide Time Called %d", timeCalledShow);
    self.scrollView.contentInset = UIEdgeInsetsZero;
    self.scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)backgroundTapped:(id)sender {
    [[[UIAlertView alloc] initWithTitle:@"Testing" message:@"Keyboard hide & show, due to alert view" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil] show];
    [self.view endEditing:YES];
}
@end

Notes

  1. I have already check keyboardWillShow called twice and similar questions here, but could not found answer
  2. It works fine with iOS 7.0
  3. Here is link of Test Code

Edit I already know the work around codes. but the real question is, how aUIAlertView can fire akeyboardWillShow notification

Edit Code I have tried Below code also suggested by @Chonch, but with this code keyboard never close even. Means keyboard appear again after closing Alert.

- (IBAction)backgroundTapped:(id)sender {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"testing" message:@"Keyboard" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction * action) {}];

    [alert addAction:defaultAction];
    [self presentViewController:alert animated:YES completion:nil];
    [self.textField resignFirstResponder];
}

Question Posted at Apple Developer Forums

Community
  • 1
  • 1
Pawan Rai
  • 3,434
  • 4
  • 32
  • 42
  • UIAlertView is deprecated starting iOS8.0: https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIAlertView_Class/index.html – Rony Rozen Aug 28 '15 at 07:10
  • this might help http://stackoverflow.com/questions/30340531/ios-keyboard-notifications-triggered-unnecessarily-upon-showing-the-alertviews-o – Abd Al-rhman Taher Badary Aug 28 '15 at 07:12
  • @AbdAl-rhmanTaherBadary I have checked it already, but it does not provide any solution. I need to know the reason behind Alert View behaviour. – Pawan Rai Aug 28 '15 at 07:16
  • 1
    @pawan it provided a solution where you unsubscribe from keyboard notifications before presenting the alert view and the subscribe again after you dismiss the alert view , anyway here is another one http://stackoverflow.com/questions/30498972/keyboard-will-appeared-automatically-in-ios-8-3-while-displaying-alertview-or-al – Abd Al-rhman Taher Badary Aug 28 '15 at 07:19
  • @AbdAl-rhmanTaherBadary I know already the work around, but i need to know how a alert view can fire a keyboardWillShow notification. – Pawan Rai Aug 28 '15 at 07:24
  • @Chonch alertcontroller does not seems to solve the problem, but it causing to appear keyboard again. – Pawan Rai Aug 28 '15 at 07:29
  • 1
    well since it is deprecated anything can happen , but it certainly a bug , but here is a good observation though http://stackoverflow.com/questions/30498972/keyboard-will-appeared-automatically-in-ios-8-3-while-displaying-alertview-or-al/30500204#30500204 – Abd Al-rhman Taher Badary Aug 28 '15 at 07:32
  • @AbdAl-rhmanTaherBadary following explanation is based on, how a keyboard state is saved in between delegate called, but as you can see in my case alert view does not implement any delegate. – Pawan Rai Aug 28 '15 at 07:39
  • @pawan since you are determined to find the answer i asked a question for you in the developer community , maybe you will find luck there https://forums.developer.apple.com/thread/15837?q=uialertview%20fi . – Abd Al-rhman Taher Badary Aug 28 '15 at 07:46
  • @AbdAl-rhmanTaherBadary Thanks – Pawan Rai Aug 28 '15 at 07:48

3 Answers3

1

UIAlertView is buggy and probably hasn't been since it was deprecated.
Replace it with UIAlertController and your problem should go away

Yariv Nissim
  • 13,273
  • 1
  • 38
  • 44
1

Not sure why it happens. It has probably something to do with UIAlertView trying to get the keyboard state back to what it was before. But note that there is no harm done with the additional show/hide calls. And in general, you need to be prepared for multiple show calls anyways, because they also come when the keyboard style is changed.

If you want to get rid of them, then use a UIAlertController instead, as suggested by Chonch already, and make sure the keyboard is dismissed before the Alert comes up, then it will work OK:

- (IBAction)backgroundTapped:(id)sender {
    [self.textField resignFirstResponder];

    alert = [UIAlertController alertControllerWithTitle:@"testing" message:@"Keyboard" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                          handler:^(UIAlertAction * action) {}];

    [alert addAction:defaultAction];
    [self presentViewController:alert animated:YES completion:nil];
}

Note that with UIAlertController, you also need to keep a reference to the alert in the viewcontroller, otherwise it will be deallocated too soon.

fishinear
  • 6,101
  • 3
  • 36
  • 84
1

I just fixed a similar issue. The keyboard keep popup after the alert dismisses It seems like a bug of apple.

There is a simple solution: If you are using AlertController, you can just set the animated to NO

[self presentViewController:alert animated:NO completion:nil];

Let me know if it fixed your problem

Yifan Fan
  • 196
  • 5