【问题标题】:Why UIAlertView prevents my modal view controller from being displayed?为什么 UIAlertView 会阻止显示我的模态视图控制器?
【发布时间】:2012-12-13 10:37:16
【问题描述】:

假设当用户按下按钮时,需要显示一条消息,然后显示一个模态视图控制器。 我会写这样的:

- (void)pickImageButtonPressed:(id)button {

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert"
                                                    message:@"Some alert"
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
    [alert release];

    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [[UIApplication sharedApplication].keyWindow.rootViewController
     presentModalViewController:picker animated:YES];
    [picker release];
}

使用此代码,模态视图控制器根本不显示

但是,如果我切换两个代码块(先显示模态,然后显示警报),视图控制器将模态显示并且警报显示在其上方,这正是我想要的。

我的问题是:为什么警报会阻止模态视图控制器显示?

请注意,在调用 presentModalViewController 之前,我不想等待警报被解除。


更新: 我发现我的生产代码比我第一次输入的要复杂一些。我更新了示例代码,终于找到了一个简单的例子来重现问题。

请注意,在我的生产代码中,弹出窗口是从我没有对视图控制器的任何引用的地方显示的,这就是我使用 [UIApplication sharedApplication].keyWindow.rootViewController 而不是直接引用的原因到视图控制器

【问题讨论】:

  • 如果“切换两个块”可以“完全按照我的意愿”工作,为什么不直接切换它们。但这是因为 UIAlertView 像 UI 元素一样在主线程上运行,但是您有另一个 UI 元素试图在同一个线程上运行,所以这就是它被延迟的原因。你不能同时在主线程上做两个 UI 事情。并且 UI 元素必须在主线程上运行。
  • 我尝试了你的代码,它的工作正如你所期望的那样
  • @Popeye 谁告诉你我们不能在主线程上做两个 UI 的事情?这样做没有问题。
  • 所以UIImagePickerController 将无法运行,直到UIAlertView 变为release/Dismissed
  • @Popeye:这有点复杂,因为在我的应用程序中,警报是在子函数中调用的,所以如果我切换“调用”,我需要添加一个丑陋的警告注释,所以没有人切换未来的电话。

标签: objective-c ios modal-dialog alert presentmodalviewcontroller


【解决方案1】:

我终于找到了答案。问题确实出在这一行:

[[UIApplication sharedApplication].keyWindow.rootViewController
 presentModalViewController:picker animated:YES];

当显示警报时,[UIApplication sharedApplication].keyWindow.rootViewController 为零!。这就是选择器从未显示的原因。这就是为什么当我切换两个块时它起作用的原因。

现在我需要找到一种方法让最相关的视图控制器以模态方式呈现选择器...

【讨论】:

  • UIAlertView 实际上在显示时接管了 keyWindow,这就是为什么你在 rootViewController 上得到 nil,因为它不再是你的 UIWindow。如果您的应用程序委托上存储了 UIWindow 属性,则可以使用该属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多