Como mostrar o indicador de carregamento na barra de status superior

120

Percebi que alguns aplicativos como Safari e Mail mostram um indicador de carregamento na barra de status (a barra na parte superior do telefone) quando eles estão acessando a rede. Existe uma maneira de fazer a mesma coisa nos aplicativos SDK ou isso é apenas uma coisa da Apple?

enferrujado
fonte

Respostas:

213

Está em UIApplication:

Para o objetivo C:

Começar:

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

Fim:

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

Para rápida:

Começar

UIApplication.shared.isNetworkActivityIndicatorVisible = true

Fim

UIApplication.shared.isNetworkActivityIndicatorVisible = false
Stephen Darlington
fonte
1
Obrigado que funciona perfeitamente. Apenas uma observação: o simulador parece ignorar esse valor, o que me fez pensar a princípio que não funcionou.
Rustyshelf 03/10/08
11
@rustyshelf, é exibido nos simuladores mais recentes.
MrHus
2
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];// como um liner
David Douglas
1
Para uso Swift sintaxeUIApplication.sharedApplication().networkActivityIndicatorVisible = true
moraisandre
2
O indicador de atividade não será exibido na barra de status do iPhone X
Melly
30

Eu achei as seguintes macros bastante úteis!

#define ShowNetworkActivityIndicator() [UIApplication sharedApplication].networkActivityIndicatorVisible = YES
#define HideNetworkActivityIndicator() [UIApplication sharedApplication].networkActivityIndicatorVisible = NO

Assim, você pode simplesmente ligar ShowNetworkActivityIndicator();ou HideNetworkActivityIndicator();de dentro do seu aplicativo (desde que o cabeçalho esteja incluído, é claro!).

Michael Waterfall
fonte
35
Por que não definir uma categoria no UIApplication? Parece muito melhor (e mais depurável) do que um #define.
Barry Wark
25

Escrevi um singleton que resolve o problema de várias conexões mantendo um contador do que está acontecendo (para evitar a remoção do status quando uma conexão retorna, mas outra ainda está ativa):

O arquivo de cabeçalho:

#import <Foundation/Foundation.h>

@interface RMActivityIndicator : NSObject

-(void)increaseActivity;
-(void)decreaseActivity;
-(void)noActivity;

+(RMActivityIndicator *)sharedManager;

@end

e implementação:

#import "RMActivityIndicator.h"

@interface RMActivityIndicator ()

@property(nonatomic,assign) unsigned int activityCounter;

@end

@implementation RMActivityIndicator

- (id)init
{
    self = [super init];
    if (self) {
        self.activityCounter = 0;
    }
    return self;
}

    -(void)increaseActivity{
        @synchronized(self) {
             self.activityCounter++;
        }
        [self updateActivity];
    }
-(void)decreaseActivity{
    @synchronized(self) {
           if (self.activityCounter>0) self.activityCounter--;
    }
    [self updateActivity];
}
-(void)noActivity{
    self.activityCounter = 0;
    [self updateActivity];
}

-(void)updateActivity{
    UIApplication* app = [UIApplication sharedApplication];
    app.networkActivityIndicatorVisible = (self.activityCounter>0);
}

#pragma mark -
#pragma mark Singleton instance

+(RMActivityIndicator *)sharedManager {
    static dispatch_once_t pred;
    static RMActivityIndicator *shared = nil;

    dispatch_once(&pred, ^{
        shared = [[RMActivityIndicator alloc] init];
    });
    return shared;
}

@end

Exemplo:

    [[RMActivityIndicator sharedManager]increaseActivity];
    [NSURLConnection sendAsynchronousRequest:urlRequest queue:self.networkReceiveProcessQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
    {
        [[RMActivityIndicator sharedManager]decreaseActivity];
    }
Resh32
fonte
3
Obrigado @Schrockwell, melhorei ainda mais usando blocos sincronizados - vi uma condição de corrida em que a atividade não era diminuída corretamente.
Resh32
3
Bom exemplo de como fazer as coisas simples difícil)
fnc12
19

Um único código de linha para fazer isso:

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
asish
fonte
5

Você também deve ocultar o indicador de atividade assim que sua chamada de rede for concluída.

Se você usa AFNetworking, não precisa fazer muito.

Faça as seguintes alterações na AppDelegateclasse:

  1. Importar AFNetworking/AFNetworkActivityIndicatorManager.h

  2. Coloque isso em didFinishLaunchingWithOptions:

[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]

Babu Lal
fonte
1
Ou com o restkit, será #import [[AFRKNetworkActivityIndicatorManager sharedManager] setEnabled: YES];
deepwinter 21/09/17
4

O indicador de atividade de rede da barra de status foi descontinuado no iOS 13 .

Usar UIApplication.shared.isNetworkActivityIndicatorVisible = truenão funcionará mais.

A mensagem de descontinuação diz:

Forneça uma interface de usuário de atividade de rede personalizada no seu aplicativo, se desejar.

M Reza F
fonte
2

Também pode ser útil verificar se você o está executando no thread principal, pois está relacionado à interface do usuário.

dispatch_async(dispatch_get_main_queue(), ^{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
});
Sev
fonte
0

Como muitos já disseram, não há indicador de atividade de rede para o iPhone X e provavelmente para os outros novos iPhones com o entalhe.

Me deparei com esta incrível biblioteca escrita por Ortwin Gentz, FutureTap: https://github.com/futuretap/FTLinearActivityIndicator

Ele coloca o indicador de volta onde estava quando o iPhone X foi lançado, muitos se lembrariam do tipo de indicador Knight Rider.

Esta biblioteca está disponível para o Swift 4.2, portanto, você precisará alterar as configurações do idioma do Swift, conforme descrito aqui: Digite 'NSAttributedStringKey' (também conhecido como 'NSString') não possui membro 'font'

erickva
fonte