62 votes

Ajouter une vue sur la barre d'état dans l'iPhone

Est-il possible d'ajouter un UIView sur la barre de menu de taille (320 x 20) ? Je ne veux pas cacher la barre d'état, je veux seulement l'ajouter au-dessus de la barre d'état.

87voto

Martin Alléus Points 3939

Vous pouvez facilement y parvenir en créant votre propre fenêtre au-dessus de la barre d'état existante.

Il suffit de créer une simple sous-classe de UIWindow avec le remplacement suivant de initWithFrame:

@interface ACStatusBarOverlayWindow : UIWindow {
}
@end

@implementation ACStatusBarOverlayWindow
- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Place the window on the correct level and position
        self.windowLevel = UIWindowLevelStatusBar+1.0f;
        self.frame = [[UIApplication sharedApplication] statusBarFrame];

        // Create an image view with an image to make it look like a status bar.
        UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.frame];
        backgroundImageView.image = [UIImage imageNamed:@"statusBarBackground.png"];
        [self addSubview:backgroundImageView];
        [backgroundImageView release];

        // TODO: Insert subviews (labels, imageViews, etc...)
    }
    return self;
}
@end

Vous pouvez maintenant, par exemple dans un contrôleur de vue de votre application, créer une instance de votre nouvelle classe et la rendre visible.

overlayWindow = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectZero];
overlayWindow.hidden = NO;

Faites attention à ne pas modifier l'état de la touche de la fenêtre en utilisant - (void)makeKeyAndVisible ou similaire. Si vous faites de votre fenêtre principale (la UIWindow dans votre délégué d'application) lâche l'état de la clé, vous rencontrerez des problèmes de défilement des vues vers le haut lorsque vous appuyez sur la barre d'état, etc.

58voto

myell0w Points 1104

J'ai écrit une bibliothèque statique imitant la barre d'état superposée de Reeders, vous pouvez la trouver ici : https://github.com/myell0w/MTStatusBarOverlay

MTStatusBarOverlayMTStatusBarOverlay

Il prend actuellement en charge l'iPhone et l'iPad, les styles de barre d'état par défaut et noir opaque, la rotation, 3 modes d'affichage différents, le suivi de l'historique et bien d'autres choses encore !

N'hésitez pas à l'utiliser ou à m'envoyer une demande de modification pour l'améliorer !

4voto

Sergey Kopanev Points 710

Toutes les réponses semblent fonctionner, mais dans iOS6.0, j'ai d'autres problèmes :

1/ Les rotations semblent mauvaises

2/ Fenêtre (la barre d'état est une sorte de fenêtre) nécessaire au rootViewController

J'utilise la réponse de myell0w mais la rotation ne fonctionne pas bien. J'ai juste supprimé une fenêtre supplémentaire et utilisé UIWindow de AppDelegate pour implémenter la barre d'état. Peut-être que cette solution n'est valable que pour une seule application UIViewController...

Je l'ai mis en œuvre de la manière suivante :

1/ Dans ApplicationDelegate :

self.window.windowLevel = UIWindowLevelStatusBar + 1;
self.window.backgroundColor = [UIColor clearColor];
self.window.rootViewController = _journalController;

2/ Créez un UIView personnalisé et implémentez tout ce dont vous avez besoin à l'intérieur : Par exemple, une barre d'état tactile :

@interface LoadingStatusBar : UIControl 

Et créer et ajouter facilement à la vue de votre contrôleur :

_loadingBar = [[LoadingStatusBar alloc] initWithFrame:topFrame];
[self addSubview:_loadingBar];

3/ Un peu de magie lors de l'ajout de votre vue contrôleur (dans initWithFrame :)

    CGRect mainFrame = self.bounds;
    mainFrame.origin.y = 20;
    self.bounds = mainFrame;

Votre vue de contrôleur aura 2 vues - vue de contenu et vue de barre d'état. Vous pouvez afficher la barre d'état, ou la cacher quand vous le souhaitez. Le cadre de la vue du contenu sera :

_contentView.frame = CGRectMake(0, 20, self.bounds.size.width, self.bounds.size.height);

4/ Et une dernière magie ici :) Pour détecter les touchers dans les zones non touchables j'ai utilisé :

-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (point.y < 20) return _loadingBar;
    return [super hitTest:point withEvent:event];
}

Pour l'instant, il fonctionne bien sur l'iPad/iPhone et tous les iOS de 4 à 6.

3voto

texmex5 Points 3187

Juste pour écarter les "Vous ne pouvez pas faire ces commentaires"...

Je ne sais pas comment mais je sais que c'est faisable. L'application Feed reader appelée Reeder fait cela.

Comme vous pouvez le voir sur la capture d'écran, Reeder place un petit point en haut à droite de l'écran. Lorsque vous le touchez. La barre remplit toute la barre d'état jusqu'à ce que vous l'effleurez à nouveau pour la rendre plus petite.

A small icon on the top right of the screenalt text

1voto

Lefteris Points 6249

Tout d'abord, un grand merci à @Martin Alléus pour avoir fourni le code de cette implémentation.

Je ne fais que poster un problème auquel j'ai été confronté et la solution que j'ai utilisée, car je pense que d'autres personnes peuvent rencontrer le même problème.

Si l'application est lancée alors qu'un appel est en cours, la hauteur de la barre d'état sera de 40 pixels, ce qui signifie que la barre d'état personnalisée sera initialisée avec cette hauteur. Mais si l'appel est terminé alors que vous êtes toujours dans l'application, la hauteur de la barre d'état restera toujours de 40 pixels et cela semblera bizarre.

La solution est donc simple : J'ai utilisé le centre de notification pour m'abonner au délégué de changement de cadre de la barre d'état de l'application et ajuster le cadre :

- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame {
    //an in call toggle was done    
    //fire notification
    [[NSNotificationCenter defaultCenter] postNotificationName:kStatusBarChangedNotification object:[NSValue valueWithCGRect:oldStatusBarFrame]];
}

Et dans la fenêtre ACStatusBarOverlayWindow, nous nous abonnons à la notification :

-(id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        // Place the window on the correct level & position
        self.windowLevel = UIWindowLevelStatusBar + 1.0f;
        self.frame = [UIApplication sharedApplication].statusBarFrame;
        self.backgroundColor = [UIColor blackColor];

        //add notification observer for in call status bar toggling
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarChanged:) name:kStatusBarChangedNotification object:nil];
    }
    return self;
}

et notre code pour ajuster le cadre :

- (void)statusBarChanged:(NSNotification*)notification {
    //adjust frame...    
    self.frame = [UIApplication sharedApplication].statusBarFrame;
    //you should adjust also the other controls you added here
}

Le site kStatusBarChangedNotification est juste une constante que j'ai utilisée pour faciliter la référence, vous pouvez simplement la remplacer par une chaîne de caractères, ou déclarer la constante globalement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X