打开多个 UIAlertView 后键盘消失
我遇到了一个奇怪的问题,当我打开多个 UIAlertView 时,键盘会自动关闭然后重新打开。如果我有一个键盘(来自单独的 UITextField)并且显示 UIAlertView,那么在解除该警报后我会打开另一个警报(在 didDismissWithButtonIndex 中打开第二个)。当我关闭第二个时,它会关闭键盘,然后键盘又会回来。如果我尝试连续发出两个以上的警报,它仍然会在第二个警报被消除后关闭我的键盘,但直到最后一个警报被消除后它才会显示。问题是键盘委托函数没有被调用,所以我无法响应它被解雇。我有其他 UI 元素(文本字段和图像),当键盘打开时,这些元素会发生移动,因此当键盘关闭时,这些元素会漂浮在屏幕上,看起来很奇怪。知道为什么键盘会自动关闭吗?谢谢
顺便说一句,我使用 NSDictionary 对象的 NSMutableArray 对已显示警报时需要显示的警报进行排队。我一次不会创建和显示超过 1 个警报。
编辑:这是示例代码。如果您运行此命令,您将看到两个警报均打开(0 然后 1),在您关闭“1”后,您将在其下方看到“0”。关闭“0”后,您就会明白我的意思 - 它们键盘会短暂关闭和打开,但不会调用委托函数。如果将 i 设置为大于 2 的值,您将看到键盘在消除第二个警报后仍然关闭,但将保持关闭状态,直到消除最后一个警报。我还尝试只打开 1 个 UIAlert,然后从队列中一次打开其他一个,因为每个 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);
}
I am having a weird issue with my keyboard automatically closing and then reopening when I open multiple UIAlertViews. If I have a keyboard (from a separate UITextField) and I display a UIAlertView, then upon dismissal of that alert I open another (opening the second one in the didDismissWithButtonIndex). When I dismiss the 2nd one it dismisses the keyboard which then comes back up. If i try this with more than 2 alerts in a row, it will still close my keyboard after the 2nd alert is dismissed, but it doesn't show up until the last alert is dismissed. The problem is that the keyboard delegate functions are NOT called so I cannot respond to it being dismissed. I have other UI elements (textfield and images) that get shifted when the keyboard opens, so when it closes those elements float in the screen and look strange. Any idea why that keyboard automatically dismisses? Thanks
BTW, I use an NSMutableArray of NSDictionary objects to queue up alerts that need to be displayed if an alert is already displayed. I am not creating and displaying more than 1 alert at a time.
EDIT: Here's sample code. If you run this you'll see both alerts open (0 then 1) after you dismiss '1' you'll see '0' under it. After you dismiss '0' you'll see what I mean - they keyboard briefly closes and opens but no delegate functions are called. If you set i to a value higher than 2, you'll see that the keyboard still closes after dismissing the 2nd alert, but will stay closed until the last alert is dismissed. I also tried opening just 1 UIAlert, and opening the others one at a time from a queue as each one was dismissed, and still noticed that same behavior. Any ideas?
EDIT: After some more digging I found that if I register for the notifications UIKeyboardDidShowNotification and UIKeyboardDidHideNotification they are in fact fired when the keyboard is automatically dismissed and presented. I still would like to know what in the underlying API is causing it to even happen so it can hopefully be avoided.
- (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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
仅当相应的 UI 元素是第一响应者时才会显示键盘。不知何故,多个警报视图会在短时间内修改响应者链。似乎是一个框架问题..
我建议这个解决方法:
编辑
实际上我现在认为它与应用程序的窗口层次结构有关。 UIAlertViews 创建自己的窗口(在窗口级别
UIWindowLevelAlert
),使它们成为接收触摸输入的关键窗口,然后在关闭时再次使旧窗口成为关键窗口。当您在 didDismiss 上显示新的警报视图时,UIKit 似乎(暂时)失去了对关键窗口和响应程序链的跟踪。上述修复当然仍然适用。
the keyboard is only shown when the corresponding UI element is the first responder.. somehow multiple alert views modify the responder chain for a short time. Seems like a framework issue..
I would suggest this workaround:
EDIT
actually i now think it has to do with the Window hierarchy of the application. UIAlertViews create their own window (at window level
UIWindowLevelAlert
), make them the key window to recieve touch input and then make the old window key window again upon dismissal. When you show a new alert view on didDismiss, UIKit seems to lose (temporarily) track of key windows and the responder chain..The fix above of course still applies.