1

我有一个关于 UIAlertController 的问题。它不能接收任何触摸事件并被解雇。我以这种方式发送警报:

UIViewController *controller =[UIApplication sharedApplication].keyWindow.rootViewController
[controller presentViewController:alertController animated:YES completion:nil];

在这段时间之后,出现了警报视图。但是当我尝试单击“确定”时,没有响应。所以我点击了alert view周围的空白区域,下层的按钮接收并做出响应。

在我的应用程序中,有一个第三方 SDK,它提供了一个暂停按钮和登录/注销 UI。该按钮将始终存在,但除非我调用它,否则不会显示 UI。SDK 在初始化时会将两个窗口添加到应用程序的窗口数组中。所以'[UIApplication sharedApplication].windows'中有三个对象。看起来像这样:

[0]:”&lt;TS_PlatformWindow: 0x16e15ac0; baseClass = UIWindow; frame = (0 0; 568 320); gestureRecognizers = <NSArray: 0x186a85b0>; layer = <UIWindowLayer: 0x186a8a20>>",
[1]:”&lt;UIWindow: 0x16e1a060; frame = (0 0; 568 320); autoresize = W+H; tag = 10000000; gestureRecognizers = <NSArray: 0x16e19af0>; layer = <UIWindowLayer: 0x16e19f40>>",
[2]:“&lt;UITextEffectsWindow: 0x16f576c0; frame = (0 0; 568 320); opaque = NO; gestureRecognizers = <NSArray: 0x16f57120>; layer = <UIWindowLayer: 0x16f574b0>>"

索引 1 处的应用程序窗口、索引 0 和 2 处的窗口是第三方 SDK。

作为 iOS 开发者库中的官方文档,引用如下:“一个事件沿着特定的路径传播,直到它被传递给可以处理它的对象。首先,单例 UIApplication 对象从队列顶部获取一个事件并调度它进行处理。通常,它将事件发送到应用程序的关键窗口对象,该对象将事件传递给初始对象进行处理。初始对象取决于事件的类型。来自https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/event_delivery_responder_chain/event_delivery_responder_chain.html

据我了解,触摸事件应该发送到应用程序的关键窗口,但实际上我的应用程序的窗口不是。该文档使用“典型”一词,因此我不确定我的应用程序中的情况是否例外。如果存在多个窗口,则没有提及事件如何传递。

所以我像这样更改我的代码:

UIViewController *controller =[UIApplication sharedApplication].keyWindow.rootViewController
for (UIWindow *win in wins.reverseObjectEnumerator) {
      UIViewController *rootController = win.rootViewController;
      if (rootController != nil) {
           controller = rootController;
           break;
     }
}
[controller presentViewController:alertController animated:YES completion:nil];

'controller' 的默认值将分配给 'keyWindow.rootViewController' 以相反的顺序移动应用程序的窗口数组,并选择最顶层对象的 'rootViewController' 来显示警报。有用!

如果这是正确的解决方案,这个问题让我感到困惑?或者有其他文件可以解释吗?</p>

PS:

每个操作都在主线程上

4

1 回答 1

0

我无法从 UIAlertController 访问背景视图,因此对当前 keyWindow 使用 addGestureRecognizer -

class MyAlertController: UIAlertController, UIGestureRecognizerDelegate {

var tapGesture : UITapGestureRecognizer?

override func viewDidAppear(animated: Bool)
{
    tapGesture = UITapGestureRecognizer(target: self, action:Selector("tapGesture:"))
    tapGesture!.delegate = self
    UIApplication.sharedApplication().keyWindow?.addGestureRecognizer(tapGesture!)
}

func tapGesture(sender: UITapGestureRecognizer? = nil)
{
    UIApplication.sharedApplication().keyWindow?.removeGestureRecognizer(tapGesture!)
    self.dismissViewControllerAnimated(true, completion: nil)
}
}
于 2015-10-16T16:13:57.793 回答