Найти UIAlertView без ссылки на него iOS 7
Я использовал фрагмент кода в моем проекте: UIAlertView без ссылки на него
Здесь код:
+ (UIAlertView *) getUIAlertViewIfShown {
if ([[[UIApplication sharedApplication] windows] count] == 1) {
return nil;
}
UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
if ([window.subviews count] > 0) {
UIView *view = [window.subviews objectAtIndex:0];
if ([view isKindOfClass:[UIAlertView class]]) {
return (UIAlertView *) view;
}
}
return nil;
}
К сожалению, он не работает в iOS 7, и я не могу отключить представление предупреждения. Во время отладки я обнаружил, что в цикле его отображение этого представления имеет класс UITransitionView
. Довольно сбивает с толку, потому что я не мог найти быстрой документации для этого класса представления.
Любые идеи, как я могу исправить эту проблему?
Ответы
Ответ 1
В iOS7 окно UIAlertView
не отображается в -[UIApplication windows]
. Фактически, UIAlertView
сам никогда не добавляется ни в какое окно, -[UIAlertView window]
всегда nil
. Вместо этого представление предупреждения управляет множеством недокументированных представлений, помещенных в -[UIApplication keyWindow]
без ссылки на представление предупреждения.
Единственная реальная опция в iOS7 - фактически отслеживать ваши предупреждения.
Ответ 2
Решение iOS 7
Class UIAlertManager = objc_getClass("_UIAlertManager");
UIAlertView *topMostAlert = [UIAlertManager performSelector:@selector(topMostAlert)];
Я не уверен, что он одобрен AppStore, но работает
Однострочный код UPD:
UIAlertView *topMostAlert = [NSClassFromString(@"_UIAlertManager") performSelector:@selector(topMostAlert)];
Ответ 3
Я столкнулся с аналогичной проблемой, и в моем случае предупреждения отображаются из разных экземпляров контроллера вида, поскольку Брайан уже упомянул, что окно UIAlertView
не отображается в [UIApplication windows]
в iOS7.
Таким образом, чтобы отслеживать этот следующий подход, можно следовать -
-
Определите константу BOOL
в App Delegate -
@property (nonatomic, assign) BOOL isAlertVisibleOnAppWindow;
-
Где присутствует "UIAlerView", проверьте наличие предыдущего экземпляра -
AppDelegate *delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
if (!delegate.isAlertVisibleOnAppWindow) {
delegate.isAlertVisibleOnAppWindow = YES;
UIAlertView *alertView = [[UIAlertView alloc] init…//alert init code
// Either handle alert cancel/completeion click here via blocks, or use alert delegates to reset the isAlertVisibleOnAppWindow BOOL variable to NO.
}
Это может быть полезно для некоторых других людей, подумавших об обмене этим.
Ответ 4
UIAlertView *topMostAlert = [NSClassFromString(@"_UIAlertManager") performSelector:@selector(topMostAlert)];
Это НЕ разрешено публиковать в Apple Store. Во время проверки сборки Xcode выдает ошибку, например: "доступ к недокументированному методу".
Поэтому вы не можете его использовать, однако этот код работает хорошо.
Ответ 5
Вы можете зарегистрироваться на UIWindowDidBecomeVisibleNotification
:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(aWindowBecameVisible:)
name:UIWindowDidBecomeVisibleNotification
object:nil];
и в aWindowBecameVisible проверьте описание окна для _UIModalItemHostingWin
:
if ([[theWindow description] hasPrefix:@"<_UIModalItemHostingWin"])
{
// This is the alert window
}