Comment afficher l'indicateur de chargement dans la barre d'état supérieure

120

J'ai remarqué que certaines applications comme Safari et Mail affichent un indicateur de chargement dans la barre d'état (la barre tout en haut du téléphone) lorsqu'elles accèdent au réseau. Existe-t-il un moyen de faire la même chose dans les applications SDK, ou est-ce une seule chose d'Apple?

rouille
la source

Réponses:

213

C'est dans UIApplication:

Pour l'objectif C:

Début:

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

Fin:

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

Pour rapide:

Début

UIApplication.shared.isNetworkActivityIndicatorVisible = true

Fin

UIApplication.shared.isNetworkActivityIndicatorVisible = false
Stephen Darlington
la source
1
Merci qui fonctionne parfaitement. Juste une remarque: le simulateur semble ignorer cette valeur, ce qui m'a fait penser au début que cela ne fonctionnait pas.
rustyshelf
11
@rustyshelf, il s'affiche dans les nouveaux simulateurs.
MrHus
2
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];// en one liner
David Douglas
1
Pour l'utilisation de la syntaxe SwiftUIApplication.sharedApplication().networkActivityIndicatorVisible = true
moraisandre
2
L'indicateur d'activité ne s'affichera pas dans la barre d'état de l'iPhone X
Melly
30

J'ai trouvé les macros suivantes très utiles!

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

Vous pouvez donc simplement appeler ShowNetworkActivityIndicator();ou HideNetworkActivityIndicator();depuis votre application (tant que l'en-tête est inclus bien sûr!).

Michael Waterfall
la source
35
Pourquoi ne pas définir une catégorie sur UIApplication? Cela semble beaucoup plus agréable (et plus déboguable) qu'un #define.
Barry Wark
25

J'ai écrit un singleton qui résout le problème des connexions multiples en gardant un compteur de ce qui se passe (pour éviter de supprimer l'état lorsqu'une connexion revient mais qu'une autre est toujours active):

Le fichier d'en-tête:

#import <Foundation/Foundation.h>

@interface RMActivityIndicator : NSObject

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

+(RMActivityIndicator *)sharedManager;

@end

et mise en œuvre:

#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

Exemple:

    [[RMActivityIndicator sharedManager]increaseActivity];
    [NSURLConnection sendAsynchronousRequest:urlRequest queue:self.networkReceiveProcessQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
    {
        [[RMActivityIndicator sharedManager]decreaseActivity];
    }
Resh32
la source
3
Merci @Schrockwell, je l'ai encore amélioré en utilisant des blocs synchronisés - j'ai vu une condition de course où l'activité n'était pas correctement diminuée.
Resh32
3
Bel exemple de comment faire des choses simples difficiles)
fnc12
19

Un code sur une seule ligne pour ce faire:

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
asish
la source
5

Vous devez prendre soin de masquer l'indicateur d'activité également une fois votre appel réseau terminé.

Si vous utilisez AFNetworking, vous n'avez pas besoin de faire grand-chose.

Effectuez les modifications suivantes en AppDelegateclasse:

  1. Importer AFNetworking/AFNetworkActivityIndicatorManager.h

  2. Mettez ça dans didFinishLaunchingWithOptions:

[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]

Babu Lal
la source
1
Ou avec restkit, ce sera #import [[AFRKNetworkActivityIndicatorManager sharedManager] setEnabled: YES];
deepwinter
4

L'indicateur d'activité du réseau de la barre d'état était obsolète dans iOS 13 .

L'utilisation UIApplication.shared.isNetworkActivityIndicatorVisible = truene fonctionnera plus.

Le message d'obsolescence dit:

Fournissez une interface utilisateur d'activité réseau personnalisée dans votre application si vous le souhaitez.

M Reza F
la source
2

Il peut également être utile de vous assurer que vous l'exécutez sur le thread principal car il est lié à l'interface utilisateur.

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

Comme beaucoup l'ont dit, il n'y a pas d'indicateur d'activité réseau pour l'iPhone X et probablement pour les autres nouveaux iPhones avec l'encoche.

Je suis tombé sur cette incroyable bibliothèque écrite par Ortwin Gentz, FutureTap: https://github.com/futuretap/FTLinearActivityIndicator

Il remet l'indicateur là où il était lorsque l'iPhone X a été initialement publié, beaucoup se souviendraient du type d'indicateur Knight Rider.

Cette bibliothèque est disponible pour Swift 4.2, vous devrez donc modifier les paramètres de Swift Language, comme décrit ici: Tapez 'NSAttributedStringKey' (aka 'NSString') n'a pas de 'police' de membre

Erickva
la source