在ios 8.3及更高版本中,UIAlertView导致keyboardWillShow& keyboardWillHide调用了两次

时间:2015-08-28 07:03:38

标签: ios objective-c xcode uialertview ios8.3

在项目工作期间,我遇到了这个问题。

其中一个控制器实现keyboardWillShow& keyboardWillHide(Apple Managing the Keyboard的标准代码)。 在后台点按,UIAlertView显示(基于某些验证),UIAlertView中只有一个按钮可以关闭UIAlertView

此处出现问题,在UIAlertViewkeyboardWillShow& keyboardWillHide再次致电。

以下是我遇到问题的代码,

#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

备注

  1. 我已在此处查看keyboardWillShow called twice及类似问题,但未找到答案
  2. 适用于iOS 7.0
  3. 以下是Test Code
  4. 的链接

    修改 我已经了解了代码的工作。但真正的问题是,UIAlertView如何触发keyboardWillShow通知

    修改代码 我已经尝试了@Chonch建议的下面的代码,但是这个代码键盘永远不会关闭。关闭警报后意味着键盘再次出现。

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

3 个答案:

答案 0 :(得分:1)

UIAlertView有问题,可能还没有被弃用。
UIAlertController替换它,你的问题应该消失

答案 1 :(得分:1)

不确定为什么会这样。它可能与UIAlertView试图将键盘状态恢复到之前的状态有关。但请注意,额外的显示/隐藏调用不会造成任何伤害。一般来说,您需要为多个节目调用做好准备,因为它们也会在键盘样式发生变化时出现。

如果你想要摆脱它们,那么就像Chonch已经建议的那样使用UIAlertController,并确保键盘在之前被解除警报出现,然后它将正常工作:

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

请注意,使用UIAlertController,您还需要在viewcontroller中保留对alert的引用,否则它将很快被释放。

答案 2 :(得分:1)

我刚刚解决了类似的问题。警报解除后,键盘会保持弹出状态 这似乎是一个苹果的错误。

有一个简单的解决方案: 如果您使用的是AlertController,则可以将动画设置为NO

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

让我知道它是否解决了您的问题