Pergunta

Eu tenho um método que publica dados HTTP e exibe um UIALERTVIEW se houver um erro. Se eu tiver várias postagens HTTP, mostrarei várias vezes em que todos os erros.

Quero mostrar um UIALERTVIEW apenas se não estiver mostrando outro UIALERTVIEW. Como posso determinar isso?

Foi útil?

Solução

No objeto que as chamadas definem um IVAR antes de invocar o método Show no seu UIALERTVIEW.

...

if (!self.alertShowing) {
    theAlert = [[UIAlertView alloc] initWithTitle:title message:details delegate:self cancelButtonTitle:nil otherButtonTitles:@"Okay", nil];
    self.alertShowing = YES;
    [theAlert show];
}

...

Então, no seu método delegado, para o alerta gerenciar a definição de sua bandeira ivar como não:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
  ...
      self.alertShowing = NO;
}

Se você deseja que os alertas apareçam sequencialmente, eu publicaria notificações para adicionar cada mensagem a uma fila e, em seguida, retire apenas uma mensagem da fila após a denúncia de um alerta.

Outras dicas

Por que não apenas verificar a propriedade visível, mantida pela classe 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];
}

Se você pode controlar as outras visualizações de alerta, verifique o visible propriedade para cada um deles.


No iOS 6 ou antes, quando um alerta aparecer, ele será movido para um _uialertoverlaywindow. Portanto, um método bastante frágil é iterar em todas as janelas e verificar se há algum subviews 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;

Isso não é documentado, pois depende da hierarquia de visualização interna, embora a Apple não possa reclamar disso. Um método mais confiável, mas ainda mais indocumentado, é verificar E se [_UIAlertManager visibleAlert] é nulo.

Esses métodos não podem verificar se é mostrado um uialertview do trampolim.

- (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;
}

Outra opção que funciona em todo o aplicativo e não envolve caminhar a pilha de visualização é a subclasse UIAlertView para MyUIAlertView, adicione uma variável estática (classe) BOOL alertIsShowing, e substituir o -(void)show Seletor.

Na sua substituição show seletor, verifique o alertIsShowing variável. Se é YES Em seguida, tente novamente após um atraso (use dispatch_after ou defina um NSTimer). Se é NO, vá em frente e ligue [super show] e atribuir YES para alertIsShowing; Quando a visualização de alerta estiver escondida, defina alertIsShowing de volta a NO (Você precisará ser inteligente em lidar com o delegado).

Finalmente, passe e substitua todos UIAlertView instâncias com MyUIAlertView.

Eu acho que vai funcionar:

-(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
}

Rápido:

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;
}

Algumas notas sobre minha busca para encontrar o Uialertview na hierarquia de visualizações:

Eu tentei percorrer todo o [UIApplication sharedApplication].windows A visualização é recursivamente, mas não conseguiu encontrar nada.

o windows propriedade de UIApplication Docs afirma o seguinte:

Esta propriedade contém os objetos UIWindow atualmente associados ao aplicativo. Esta lista não inclui o Windows criado e gerenciado pelo sistema, como a janela usada para exibir a barra de status.

Então isso me fez perceber que o UIWindow Onde UIAlertView Pode estar localizado nem é apresentado a nós.

No entanto, há também uma propriedade em UIApplication chamado keyWindow. Ao percorrer isso, encontrei aulas particulares que comporiam uma visão de alerta:

No iOS 7: _UIModalItemHostingWindow, _UIModalItemAlertContentView, _UIBackdropEffectView etc.

No iOS 8: _UIAlertControllerActionView, _UIAlertControllerShadowedScrollView, _UIBackdropView etc.

Eu não consegui encontrar o UIAlertView que eu apresentei, mas um monte de aulas que o compõem internamente. Então, para responder à pergunta original, você provavelmente pode usar o keyWindow Propriedade e veja se você percebe essas aulas, mas seu aplicativo pode ser rejeitado por tentar verificar se há aulas particulares.

Para as pessoas que usam, o mais recente, UIAlertController Disponível para o iOS 8 poderia obter a referência a ele usando:[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top