web-dev-qa-db-fra.com

Déplacer la barre d'état dans iOS 7

Le problème auquel je suis confronté est le suivant:

Je veux implémenter une application iOS 7 avec un joli design et un menu gauche/droite, qui apparaît après que la vue principale s'anime à droite/gauche. Je fais ça avec [UIView animateWithDuration...] code, mais ce n'est pas vraiment important. Ce que je veux obtenir, c'est le même effet que l'application Mailbox iOS 7: déplacer la barre d'état (à droite/à gauche) avec la vue principale

Image pour une meilleure explication:

Mailbox app with status bar moved to the side

Ce que j'ai trouvé, c'est this article sur le problème, avec du code de travail utilisant des API privées, que je ne voudrais pas utiliser, car je veux que mon application soit acceptée sur l'App Store.

Je voudrais obtenir le même effet ("légalement"). Quelqu'un sait-il comment?

Merci!

36
Gyfis

L'essentiel est d'utiliser cette méthode introduite dans iOS 7:

https://developer.Apple.com/documentation/uikit/uiscreen/1617814-snapshotview :

Avec cela, vous obtenez une UIView contenant une capture d'écran qui comprend la barre d'état. Une fois que vous avez cela, il suffit de cacher votre vue actuelle, puis de pousser la vue de capture d'écran.

J'ai posté une preuve de concept ici: https://github.com/simonholroyd/StatusBarTest

[~ # ~] note [~ # ~] Je n'ai pas soumis de code qui le fait via le Apple processus d'examen, mais ce n'est pas une méthode d'API privée.

48
Simon Holroyd

Ainsi, après la poussée initiale de M. Simon Holroyd et quelques recherches, j'ai trouvé la solution pour obtenir cette fonctionnalité "d'effet". Voici le code:

statusbarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];

EDIT: monsieur pcholberg a correctement souligné que l'ancien code ne fonctionnait pas sur le périphérique réel, uniquement sur le simulateur iOS, donc je l'ai modifié par sa recommandation

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
{
    UIView *screenShot = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
    [statusbarView addSubview:screenShot];
    [statusbarView setClipsToBounds:YES];
    [self.view addSubview:statusbarView];

    [self setPrefersStatusBarHidden:YES];
    [self prefersStatusBarHidden];
    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
}

...

- (BOOL)prefersStatusBarHidden
{
    return prefersStatusBarHidden;
}

...


La première partie crée donc le contexte, utilise la méthode mentionnée par Simon, dessine la vue avec la barre d'état et l'enregistre en tant que UIImage

La deuxième partie ajoute l'instantané UIView à mon viewController UIView

Et la troisième partie définit mon booléen pour la barre d'état sur OUI (pour une utilisation plus facile dans la méthode ci-dessus), et appelle des méthodes pour le redessiner

Cela définit ensuite l'UIView comme une barre d'état non fonctionnelle à sa place et masque celle d'origine, il n'y a donc pas de double rendu. Ensuite, je peux utiliser cette vue dans mon [UIView animateWithDuration... méthode

Et quand je reviens, j'utilise ce code dans le gestionnaire d'achèvement du bloc d'animation:

[statusbarView removeFromSuperview];

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
{

    [self setPrefersStatusBarHidden:NO];
    [self prefersStatusBarHidden];
    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];

}

Et voilá! Cela fonctionne comme l'effet décrit dans ma question.

J'espère que cela aide quelqu'un!

7
Gyfis

J'utilise cette méthode pour déplacer la barre de statue avec la vue du curseur, dans une application, il y a deux fenêtres, une fenêtre normale, l'autre statuBarWindow, j'obtiens statuBarView dont superView est statuBarWindows et le déplace avec la vue du curseur.

- (UIView *)statuBarView
{
    NSString *key = [[NSString alloc] initWithData:[NSData dataWithBytes:(unsigned char []){0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x72} length:9] encoding:NSASCIIStringEncoding];
    id object = [UIApplication sharedApplication];
    UIView *statusBar = nil;
    if ([object respondsToSelector:NSSelectorFromString(key)]) {
        statusBar = [object valueForKey:key];
    }
    return statusBar;
}
7
signal

Je viens de créer BSPanViewController ce qui rend extrêmement facile l'obtention de cet effet. Le contrôle et les instructions sur la façon de l'utiliser peuvent être trouvés sur GitHub .

L'implémentation est la même que celle expliquée par Simon Holroyd .

3
simonbs