2016-05-16 1 views
1

J'ai un problème dans mon application où il y a une barre noire en haut de l'application et toute ma vue est poussée vers le bas à 20 pts du haut.iOS 9 bug de barre d'état étendu?

Voici un exemple de projet très court qui reproduit le bug: https://github.com/sbiermanlytle/iOS-status-bar-bug/tree/master

Reproduire:

  1. Activez la barre d'état étendu (commencer un itinéraire sur Google Maps ou mettez un point d'accès)
  2. Démarrez l'application de démonstration
  3. Naviguez jusqu'au 3ème vue
  4. Retour à la 2ème vue, vous verrez la barre noire en haut

Comment se débarrasser de la barre noire?

Voici une explication complète de l'exemple d'application:

Il y a une série de 3 vue des contrôleurs, 1 lance 2, UIViewControllerBasedStatusBarAppearance est réglé selon YES, les 1er et 3e contrôleurs Masquer la barre d'état, et le 2ème le montre. Tout s'affiche bien lorsque vous lancez la 2ème vue et la 3ème vue, mais lorsque vous fermez la 3ème vue, il y a une barre noire en haut de la 2ème vue qui ne va pas disparaître.

+2

Dans SecondViewController dans buttonPush change nav.modalTransitionStyle = UIModalPresentationPopover; à nav.modalPresentationStyle = UIModalPresentationOverCurrentContext; – beyowulf

+0

Toujours en train de voir la barre noire - avez-vous testé avec la barre d'état étendue active? – Cbas

+0

Oui, j'ai testé sur appareil et en simulateur (commande + Y). – beyowulf

Répondre

1

On dirait iOS bug.

Je ne sais pas une belle façon de contourner cela, mais ces œuvres certainement:


utiliser l'API dépréciée

Changer d'entrée View controller-based status bar appearance dans Info.plist à NO. Ajouter un code comme celui-ci à tous de vos contrôleurs de vue (ou superclasse commune, espérons que vous avez un;)):

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    [[UIApplication sharedApplication] setStatusBarHidden:[self prefersStatusBarHidden]]; 
} 

Utilisez tweak laid

par image mise à jour manuelle du système défaillant vue à l'origine de la condition. Cela peut ou peut ne pas casser quelque chose en dehors de l'application de test.

Dans UIViewController+TheTweak.h

#import <UIKit/UIKit.h> 

@interface UIViewController (TheTweak) 

- (void)transitionViewForceLayoutTweak; 

@end 

Dans UIViewController+TheTweak.m (esprit le commentaire FIXME)

#import "UIViewController+TheTweak.h" 
#import "UIView+TheTweak.h" 

@implementation UIViewController (TheTweak) 

- (void)transitionViewForceLayoutTweak { 
    UIViewController *presenting = [self presentingViewController]; 
    if (([self presentedViewController] != nil) && ([self presentingViewController] != nil)) { 
     if ([self prefersStatusBarHidden]) { 

      NSUInteger howDeepDownTheStack = 0; 
      do { 
       ++howDeepDownTheStack; 
       presenting = [presenting presentingViewController]; 
      } while (presenting != nil); 

      //FIXME: replace with a reliable way to get window throughout whole app, without assuming it is the 'key' one. depends on your app's specifics 
      UIWindow *window = [[UIApplication sharedApplication] keyWindow]; 
      [window forceLayoutTransitionViewsToDepth:howDeepDownTheStack]; 
     } 
    } 
} 

@end 

Dans UIView+TheTweak.h

#import <UIKit/UIKit.h> 

@interface UIView (TheTweak) 

- (void)forceLayoutTransitionViewsToDepth:(NSUInteger)depth; 

@end 

En UIView+TheTweak.m

#import "UIView+TheTweak.h" 

@implementation UIView (TheTweak) 

- (void)forceLayoutTransitionViewsToDepth:(NSUInteger)depth { 
    if (depth > 0) { //just in case 
     for (UIView *childView in [self subviews]) { 
      if ([NSStringFromClass([childView class]) isEqualToString:@"UITransitionView"]) { 
       childView.frame = self.bounds; 
       if (depth > 1) { 
        [childView forceLayoutTransitionViewsToDepth:(depth - 1)]; 
       } 
      } 
     } 
    } 
} 

@end 

Maintenant, dans chaque contrôleur de vue (ou superclasse commune):

#import "UIViewController+TheTweak.h" 

... // whatever goes here 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    [self transitionViewForceLayoutTweak]; 
} 

Ou votre peut simplement tourner arrière-plan du contrôleur problématique noir :)

+0

Je ne peux pas utiliser l'API dépréciée b/c J'ai rencontré un problème avec elle plus tôt et j'ai dû passer à la nouvelle. De plus, je ne peux pas noircir l'écran car il y a en fait une image et une barre inférieure qui est repoussée hors de l'écran. Le hack de la fenêtre fonctionne parfaitement dans l'application de démonstration! va devoir voir si cela gâche la mise en page ailleurs – Cbas

+0

fonctionne très bien dans mon application complète aussi – Cbas

+0

Juste se soucier de la version iOS. Ce détail particulier de la hiérarchie des vues n'est pas documenté et peut ou non changer un jour, avec une chance de casser des choses. Je recommande de revenir à la mise en œuvre «normale» dès qu'Apple le corrige. –

0

Simplest tweak

@interface SecondViewController() 

@property (assign, nonatomic) BOOL statusBarHidden; 

@end 

@implementation SecondViewController 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    self.statusBarHidden = [UIApplication sharedApplication].statusBarHidden; //store current state 
} 

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    self.statusBarHidden = YES; 
    [UIView animateWithDuration:0.2f animations:^{ 
    [self setNeedsStatusBarAppearanceUpdate]; 
    }]; 
} 

- (BOOL)prefersStatusBarHidden { 
    return self.statusBarHidden; 
} 
@end