【问题标题】:In ios 8.3 and later, UIAlertView cause keyboardWillShow & keyboardWillHide called twice在 ios 8.3 及更高版本中,UIAlertView 导致 keyboardWillShow & keyboardWillHide 调用了两次
【发布时间】:2015-08-28 07:03:38
【问题描述】:

在做项目时,我遇到了这个问题。

其中一个控制器实现keyboardWillShowkeyboardWillHide(来自Apple 的标准代码Managing the Keyboard)。 在后台点击时,UIAlertView 出现(基于一些验证),UIAlertView 中只有一个按钮可以简单地关闭UIAlertView

问题出现在这里,UIAlertView 关闭时,keyboardWillShowkeyboardWillHide 再次调用。

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

#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的链接

编辑 我已经知道代码的工作了。但真正的问题是,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

【问题讨论】:

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


【解决方案1】:

UIAlertView 有问题,可能自从它被弃用后就没有了。
将其替换为 UIAlertController,您的问题应该会消失

【讨论】:

  • 我认为您没有看到编辑代码部分。请在发布任何答案之前检查它。
  • 你能说得更具体点吗?
【解决方案2】:

不知道为什么会这样。它可能与 UIAlertView 试图将键盘状态恢复到以前的状态有关。但请注意,额外的显示/隐藏调用不会造成任何伤害。通常,无论如何,您都需要为多个演出电话做好准备,因为它们也会在键盘样式更改时出现。

如果您想摆脱它们,请改用 UIAlertController,正如 Chonch 已经建议的那样,并确保在警报出现之前 关闭键盘,然后它会正常工作:

- (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,您还需要在视图控制器中保留对警报的引用,否则它会很快被释放。

【讨论】:

    【解决方案3】:

    我刚刚修复了一个类似的问题。警报消失后键盘继续弹出 好像是苹果的bug。

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

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

    如果它解决了您的问题,请告诉我

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多