Вопрос

У меня есть метод, который публикует данные 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top