【发布时间】:2015-04-07 03:29:39
【问题描述】:
我有一个关于 UIAlertController 的问题。它不能接收任何触摸事件并被解雇。 我以这种方式发送警报:
UIViewController *controller =[UIApplication sharedApplication].keyWindow.rootViewController
[controller presentViewController:alertController animated:YES completion:nil];
在这个时间之后,出现了警报视图。但是当我尝试单击“确定”时,没有任何响应。于是我点击了alert view周围的空白区域,下层的按钮接收并做出响应。
在我的应用程序中,有一个第三方 SDK,它提供了一个暂停按钮和登录/注销 UI。该按钮将始终存在,但除非我调用它,否则不会显示 UI。 SDK 在初始化时会将两个窗口添加到应用程序的窗口数组中。 所以“[UIApplication sharedApplication].windows”中有三个对象。 看起来像这样:
[0]:”<TS_PlatformWindow: 0x16e15ac0; baseClass = UIWindow; frame = (0 0; 568 320); gestureRecognizers = <NSArray: 0x186a85b0>; layer = <UIWindowLayer: 0x186a8a20>>",
[1]:”<UIWindow: 0x16e1a060; frame = (0 0; 568 320); autoresize = W+H; tag = 10000000; gestureRecognizers = <NSArray: 0x16e19af0>; layer = <UIWindowLayer: 0x16e19f40>>",
[2]:“<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”来显示警报。 有效!
如果这是正确的解决方案,这个问题让我感到困惑?或者有其他文件可以解释吗?
PS:
每个操作都在主线程上
【问题讨论】:
标签: touch dismiss uialertcontroller keywindow