Проверьте, показывает ли uialertview
-
22-09-2019 - |
Вопрос
У меня есть метод, который публикует данные HTTP и отображает uialertView, если есть ошибка. Если у меня есть несколько сообщений HTTP, я покажу несколько UialertView для каждой ошибки.
Я хочу показать uialertview, только если не показывает другой uialertview. Как я могу это определить?
Решение
На объекте, который вызовет, устанавливает ivar, прежде чем вызывать метод шоу на вашем UialertView.
...
if (!self.alertShowing) {
theAlert = [[UIAlertView alloc] initWithTitle:title message:details delegate:self cancelButtonTitle:nil otherButtonTitles:@"Okay", nil];
self.alertShowing = YES;
[theAlert show];
}
...
Затем в вашем методе делегата для управления оповещением устанавливает свой флаг ivar на нет:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
...
self.alertShowing = NO;
}
Если вы хотите, чтобы предупреждения показали последовательно, я бы опубликовал уведомления, чтобы добавить каждое сообщение в очередь, а затем снять сообщение только после увольнения.
Другие советы
Почему бы просто не проверить видимое свойство, поддерживаемое классом uialertview?
if (_alert) //alert is a retained property
{
self.alert = [[[UIAlertView alloc] initWithTitle:@"Your Title"
message:@"Your message"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK"] autorelease];
}
if (!_alert.visible)
{
[_alert show];
}
Если вы можете управлять другими видами оповещения, проверьте visible
собственность для каждого из них.
В iOS 6 или раньше, когда появляется предупреждение, оно будет перемещено в _uialertoverlaywindow. Следовательно, довольно хрупкий метод заключается в том, чтобы итерация через все Windows и проверить, есть ли какие -либо подвесы UialertView.
for (UIWindow* window in [UIApplication sharedApplication].windows) {
NSArray* subviews = window.subviews;
if ([subviews count] > 0)
if ([[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]])
return YES;
}
return NO;
Это незарегистрировано, поскольку это зависит от иерархии внутреннего представления, хотя Apple не может жаловаться на это. Более надежный, но еще более недокументированный метод - проверить если [_UIAlertManager visibleAlert]
ноль.
Эти методы не могут проверить, отображается ли uialertview с трамплина.
- (BOOL)checkAlertExist {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
NSArray* subviews = window.subviews;
if ([subviews count] > 0) {
for (id cc in subviews) {
if ([cc isKindOfClass:[UIAlertView class]]) {
return YES;
}
}
}
}
return NO;
}
Еще один вариант, который работает по всему приложению и не включает в себя ходьбу стека представления, - это подкласс UIAlertView
к MyUIAlertView
, добавить статическую (классовую) переменную BOOL alertIsShowing
, и переопределить -(void)show
селектор.
В вашем переопределении show
Селектор, проверьте alertIsShowing
переменная. Если это YES
Затем попробуйте еще раз после задержки (используйте dispatch_after
или установить NSTimer
) Если это NO
, давай и позвоните [super show]
и назначить YES
к alertIsShowing
; Когда скрывается представление о предупреждении, установите alertIsShowing
вернуться к NO
(Вам нужно быть умным в обращении с делегатом).
Наконец, пройдите и замените все UIAlertView
экземпляры с MyUIAlertView
.
Я думаю, что это сработает:
-(BOOL) doesAlertViewExist {
if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])
{
return NO;//AlertView does not exist on current window
}
return YES;//AlertView exist on current window
}
Быстрый:
func showAlert(withTitle title: String, message: String, viewController: UIViewController) {
if viewController.presentedViewController == nil { // Prevent multiple alerts at the same time
let localizedTitle = NSLocalizedString(title, comment: "")
let localizedMessage = NSLocalizedString(message, comment: "")
let alert = UIAlertController(title: localizedTitle, message: localizedMessage, preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
alert.addAction(action)
viewController.presentViewController(alert, animated: true, completion: nil)
}
}
// initialize default flag for alert... If alert is not open set isOpenAlert as NO
BOOL isAlertOpen;
isAlertOpen = NO;
if (isAlertOpen == NO) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Alert is Open" delegate:self cancelButtonTitle:@"Okay!!" otherButtonTitles: nil];
[alert show];
// Now set isAlertOpen to YES
isAlertOpen = YES;
}
else
{
//Do something
}
+ (BOOL)checkAlertExist {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
if ([window.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
return YES;
}
}
return NO;
}
Некоторые заметки о моем стремлении найти UialertView в иерархии просмотра:
Я пытался пройти через все [UIApplication sharedApplication].windows
Взгляд рекурсивно, но ничего не смог найти.
А windows
свойство UIApplication
Документы заявляют следующее:
Это свойство содержит объекты UIWindow, которые в настоящее время связаны с приложением. Этот список не включает Windows, созданные и управляемые системой, например, окно, используемое для отображения строки состояния.
Так что это заставило меня понять, что UIWindow
куда UIAlertView
может быть расположен даже не представлен нам.
Тем не менее, есть также собственность на UIApplication
называется keyWindow
. Анкет После того, как я прошел через это, я нашел частные классы, которые составляли бы предупреждающий представление:
На iOS 7: _UIModalItemHostingWindow
, _UIModalItemAlertContentView
, _UIBackdropEffectView
и т.п.
На iOS 8: _UIAlertControllerActionView
, _UIAlertControllerShadowedScrollView
, _UIBackdropView
и т.п.
Я не мог найти UIAlertView
Что я представил, а скорее куча классов, которые составляют его внутри. Итак, чтобы ответить на исходный вопрос, вы, вероятно, можете использовать keyWindow
Собственность и посмотрите, заметите ли вы эти классы, но ваше приложение может быть отклонено за попытку проверить на частные занятия.
Для людей, использующих, новее, UIAlertController
Доступно для iOS 8 может получить ссылку на него, используя:[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController
.