1

当我打开多个 UIAlertViews 时,我的键盘自动关闭然后重新打开时遇到了一个奇怪的问题。如果我有一个键盘(来自一个单独的 UITextField)并且我显示了一个 UIAlertView,那么在解除该警报后,我会打开另一个(在 didDismissWithButtonIndex 中打开第二个)。当我关闭第二个时,它会关闭键盘,然后重新启动。如果我连续尝试超过 2 个警报,它仍然会在第二个警报被解除后关闭我的键盘,但直到最后一个警报被解除后才会显示。问题是没有调用键盘委托函数,所以我无法响应它被解雇。我还有其他 UI 元素(文本字段和图像)在键盘打开时会发生变化,所以当它关闭时,这些元素会漂浮在屏幕上,看起来很奇怪。知道为什么那个键盘会自动关闭吗?谢谢

顺便说一句,如果警报已经显示,我使用 NSMutableArray 的 NSDictionary 对象来排队需要显示的警报。我一次没有创建和显示超过 1 个警报。

编辑:这是示例代码。如果您运行此命令,您将在关闭“1”后看到两个警报都打开(0 然后 1),您将在其下方看到“0”。在您关闭“0”后,您会明白我的意思 - 他们的键盘会短暂关闭和打开,但不会调用委托函数。如果您将 i 设置为大于 2 的值,您会看到键盘在关闭第二个警报后仍然关闭,但会保持关闭直到最后一个警报被关闭。我还尝试只打开 1 个 UIAlert,并在每个都被解雇时从队列中一次打开其他一个,但仍然注意到相同的行为。有任何想法吗?

编辑:经过更多挖掘后,我发现如果我注册通知 UIKeyboardDidShowNotification 和 UIKeyboardDidHideNotification ,它们实际上会在键盘自动关闭和呈现时被触发。我仍然想知道底层 API 中的什么导致它发生,因此希望可以避免。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
// Override point for customization after application launch.
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 100, 320, 48)];
[textField setDelegate:self];
[textField setBackgroundColor:[UIColor redColor]];
[window addSubview:textField];
[textField release];
[self.window makeKeyAndVisible];
return YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *) textField{
NSLog(@"textFieldShouldReturn called with %@", textField);
[textField resignFirstResponder];
return YES;
}


-(void) textFieldDidBeginEditing:(UITextField *)textField 
{
NSLog(@"textFieldDidBeginEditing called with %@", textField);
for (int i=0; i< 2; i++) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @"test" message: [NSString stringWithFormat:@"%d", i] delegate:self cancelButtonTitle:NSLocalizedString(@"OK",@"") otherButtonTitles:nil];
    [alert show];
    [alert release];
}
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
NSLog(@"++++ textFieldShouldEndEditing %@", textField);
return YES;
}

-(void) textFieldDidEndEditing:(UITextField *)textField
{
NSLog(@"++++ textFieldDidEndEditing %@", textField);

}
4

1 回答 1

4

仅当相应的 UI 元素是第一响应者时才显示键盘。不知何故,多个警报视图会在短时间内修改响应者链。好像是框架问题。。

我会建议这种解决方法:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    dispatch_async(dispatch_get_main_queue(), ^{
        /* show new alert view here */
    });
}

编辑

实际上我现在认为它与应用程序的 Window 层次结构有关。UIAlertViews 创建自己的窗口(在窗口级别UIWindowLevelAlert),使它们成为接收触摸输入的关键窗口,然后在解除时再次使旧窗口关键窗口。当您在 didDismiss 上显示新的警报视图时,UIKit 似乎(暂时)丢失了对关键窗口和响应者链的跟踪。
当然上面的修复仍然适用。

于 2011-09-29T18:16:15.147 回答