web-dev-qa-db-fra.com

Ajout de la vue sur StatusBar dans l'iPhone

Est-il possible d'ajouter une UIView sur la barre d'état de taille (320 x 20)? Je ne veux pas masquer la barre d'état, je veux seulement l'ajouter en haut de la barre d'état.

62
Biranchi

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

Créez simplement une sous-classe simple 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;

Soyez conscient de jouer avec l'état de la clé de la fenêtre en utilisant - (void)makeKeyAndVisible ou similaire. Si vous rendez votre fenêtre principale (le UIWindow dans votre délégué d'application) lâche, vous rencontrerez des problèmes avec le défilement des vues de défilement vers le haut lorsque vous appuyez sur la barre d'état, etc.

87
alleus

J'ai écrit une bibliothèque statique imitant la superposition de la barre d'état 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 noirs par défaut et opaques, la rotation, 3 modes d'anymation différents, le suivi de l'historique et bien d'autres goodies!

N'hésitez pas à l'utiliser ou à m'envoyer une Pull Request pour l'améliorer!

58
myell0w

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

1/Les rotations semblent mauvaises

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

J'utilise la réponse de myell0w, mais la rotation ne fonctionne pas bien. Je viens de supprimer une fenêtre supplémentaire et d'utiliser UIWindow d'AppDelegate pour implémenter la barre d'état. Peut-être que cette solution est correcte uniquement pour une application UIViewController ...

Ive implémenté par la voie suivante:

1/En demande Délégué:

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

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

@interface LoadingStatusBar : UIControl 

Et créez et ajoutez 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 la vue de votre contrôleur (dans initWithFrame :)

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

La vue de votre contrôleur aura 2 vues - vue du contenu et vue de la barre d'état. Vous pouvez afficher la barre d'état ou la masquer quand vous le souhaitez. Le cadre de l'affichage 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 touches dans la zone non tactile 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, cela fonctionne bien sur iPad/iPhone et tous les iOS de 4 à 6.

4
Sergey Kopanev

Juste pour rejeter le "Vous ne pouvez pas faire ces commentaires" ...

Je ne sais pas comment mais je sais que c'est faisable. L'application de lecture de flux appelée Reeder le fait.

Comme vous pouvez le voir sur la capture d'écran, Reeder place un petit point en haut à droite de l'écran. Lorsque vous appuyez dessus. La barre remplira toute la barre d'état jusqu'à ce que vous la tapotiez à nouveau pour la réduire.

A small icon on the top right of the screenalt text

3
texmex5

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

Je poste juste pour un problème que j'ai rencontré et la solution que j'ai utilisée, car je pense que d'autres pourraient rencontrer le même problème.

Si l'application est démarrée pendant un appel, la hauteur de la barre d'état sera de 40 pixels et cela signifie que la barre d'état personnalisée sera initialisée avec cette hauteur. Mais si l'appel se termine alors que vous êtes encore dans l'application, la hauteur de la barre d'état restera toujours de 40 pixels et elle aura l'air bizarre.

La solution est donc simple: j'ai utilisé le centre de notifications 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 l'ACStatusBarOverlayWindow, nous souscrivons à 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 kStatusBarChangedNotification est juste une constante que j'ai utilisée pour une référence facile, vous pouvez simplement le remplacer par une chaîne ou déclarer la constante globalement.

1
Lefteris