UIAlertController в iOS 8.x не может ответить на событие касания, отправлено ли событие касания объекту ключевого окна?
У меня проблема с UIAlertController. Он не может получать какие-либо события касания и быть отклоненным. Я передаю предупреждение следующим образом:
UIViewController *controller =[UIApplication sharedApplication].keyWindow.rootViewController
[controller presentViewController:alertController animated:YES completion:nil];
По истечении этого времени был показан вид оповещения. Но когда я пытаюсь нажать "ОК", ответа нет. Поэтому я щелкаю пустую область вокруг окна с предупреждением, кнопка на нижнем уровне получает его и дает ответ.
В моем приложении есть сторонний SDK, который предоставляет кнопку приостановки и интерфейс входа / выхода. Кнопка всегда будет там, но пользовательский интерфейс не будет отображаться, пока я не позвоню. 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 Developer Library, здесь есть цитата: "Событие проходит по определенному пути, пока не будет доставлено объекту, который может его обработать. Во-первых, одноэлементный объект 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:
Все операции находятся в главном потоке
1 ответ
Я не могу получить доступ к фоновому представлению из UIAlertController, поэтому использую addGestureRecognizer для текущего keyWindow -
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)
}
}