iOS 7 - La barre d'état chevauche la vue

109

J'ai un ViewControllerqui est à l'intérieur de a UINavigationcontroller, mais la barre de navigation est cachée. Lorsque j'exécute l'application sur iOS 7, la barre d'état s'affiche en haut de ma vue. Y a-t-il un moyen d'éviter cela?

Je ne veux pas écrire de code spécifique au système d'exploitation.

Entrez la description de l'image ici

Je mise essayé View controller-based status bar appearancede NO, mais il n'a pas résolu la question.

aryaxt
la source
J'ai publié ma réponse pour afficher la barre d'état comme iOS 6 dans iOS 7 stackoverflow.com/questions/18294872/…
Desert Rose
2
Vous devez également ajuster l'origine y et la valeur delta pour gérer le problème de la barre d'état. Cela peut vous aider à stackoverflow.com/q/18980925/1545180
Ganapathy

Réponses:

95

Xcode 5 iOS 6/7 Deltasest spécialement conçu pour résoudre ce problème. Dans le storyboard, j'ai déplacé mes vues de 20 pixels vers le bas pour avoir l'air droit sur iOS 7 et afin de le rendre compatible avec iOS 6, je suis passé Delta yà -20.

entrez la description de l'image ici

Depuis mon story - board n'utilise la configuration automatique, afin de redimensionner la hauteur des vues correctement sur iOS 6 je devais mettre Delta heightainsi que Delta Y.

aryaxt
la source
8
votre réponse est correcte mais ne fonctionne pas avec un écran de 4 ". Veuillez mettre à jour votre réponse si vous pouvez également la faire fonctionner pour un écran de 4". Merci d'avance.
2
@AnkitMehta Je n'ai rien eu à faire de spécifique pour les iphones 4 "
aryaxt
5
travaillé pour moi. Notez que pour voir ces deltas, vous devez désélectionner «Utiliser la mise en page automatique» sous «Identité et type» pour le storyboard.
marsant
2
J'ai découvert qu'en plus de définir un -20 pour ∆Y, je devais également définir un +20 à ∆Height
Toland Hon
3
Que se passe-t-il lorsque la hauteur de la barre d'état change? Par exemple: lorsque l'utilisateur active le point chaud, etc .... alors la hauteur est de 40px ...
Lukasz
69

Si vous ne voulez tout simplement PAS de barre d'état, vous devez mettre à jour votre plist avec ces données: Pour ce faire, dans le plist, ajoutez ces 2 paramètres:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Dans iOS 7, vous devez concevoir votre application en gardant à l'esprit une barre d'état transparente superposée. Voir la nouvelle application Météo iOS 7 par exemple.

Nathan H
la source
3
C'est en fait la seule bonne réponse car elle résout le problème au cœur de la manière dont il était censé être fait. Donc: des votes positifs sont nécessaires!
onze59
5
Cela peut être approprié dans certaines situations, mais vous devez faire très attention en cachant la barre d'état. Uniquement pour les vues qui sont à juste titre en plein écran, comme les lecteurs multimédias ou les visionneuses d'images.
smileBot
1
@ eleven59, vous voulez dire la façon dont les autocrates d'Apple ont l'intention.
JohnK
1
Certainement mieux comme ça que de changer le décalage d'un contrôleur de vue (qui semble vraiment sale).
Benjamin Oman
masquer la barre d'état n'est pas une bonne idée ... Je sais que c'est le moyen le plus simple de gérer iOS 7, mais le timing est NÉCESSAIRE ...
Fahim Parkar
43

Il s'agit du comportement par défaut pour UIViewControlleriOS 7. La vue sera en plein écran, ce qui signifie que la barre d'état couvrira le haut de votre vue.

Si vous avez un UIViewControllerdans un UINavigationControlleret que navigationBar est visible, vous pouvez avoir le code suivant dans votre viewDidLoadou avoir une image d'arrière-plan pour navigationBar faire l'affaire.

self.edgesForExtendedLayout = UIRectEdgeNone;

Si navigationBar est masqué, vous devez ajuster tous les éléments UIView en décalant de 20 points. Je ne vois aucune autre solution. Utiliser la mise en page automatique aidera un peu.

Voici l'exemple de code pour détecter la version iOS, si vous souhaitez une compatibilité descendante.

NSUInteger DeviceSystemMajorVersion() {
    static NSUInteger _deviceSystemMajorVersion = -1;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSString *systemVersion = [UIDevice currentDevice].systemVersion;
        _deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
    });

   return _deviceSystemMajorVersion;
}
Vincent
la source
18
Au lieu de récupérer, d'analyser et de comparer la version du système, il est recommandé d'utiliserif ([self respondsToSelector:@selector(edgesForExtendedLayout)])
Sebastian Hojas
15

La seule solution de travail que j'ai faite par moi-même.

Voici ma sous-classe UIViewController https://github.com/comonitos/ios7_overlaping

1 Sous-classe de UIViewController

2 Sous-classez votre window.rootViewController de cette classe.

3 Voila!

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

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect screen = [[UIScreen mainScreen] bounds];
        if (self.navigationController) {
            CGRect frame = self.navigationController.view.frame;
            frame.origin.y = 20;
            frame.size.height = screen.size.height - 20;
            self.navigationController.view.frame = frame;
        } else {
            if ([self respondsToSelector: @selector(containerView)]) {
                UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];

                CGRect frame = containerView.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                containerView.frame = frame;
            } else {
                CGRect frame = self.view.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                self.view.frame = frame;
            }
        }
    }
}

4 Ajoutez ceci pour rendre votre barre d'état blanche Juste après [self.window makeKeyAndVisible]; !!!

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
comonitos
la source
mais cela ne montre pas l'heure au sommet ... Le plus gros inconvénient ... :(
Fahim Parkar
Fonctionne très bien, mais pour l'étape 4, vous devez utiliser favoriteStatusBarStyle dans votre contrôleur de vue, car setStatusBarStyle est obsolète et son action par défaut est de ne rien faire. stackoverflow.com/a/19014724/1192732
CpnCrunch
13
-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

-(void)viewWillLayoutSubviews{

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
  {
    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
        screenHeight = screenRect.size.height;
    else
        screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
    CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
    if (!CGRectEqualToRect(screenFrame, viewFrame1))
    {
        self.view.frame = screenFrame;
        self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }
  }
}

Ajouter une clé dans plist --- Afficher l'apparence de la barre d'état basée sur le contrôleur: NON

Darshit Shah
la source
changer la couleur de la fenêtre si nécessaire
Darshit Shah
Merci, cela a résolu mon problème de chevauchement. Mais un problème toujours là - Afficher l'apparence de la barre d'état basée sur le contrôleur: NON est de masquer la barre d'état, je suppose. Mais lorsque je le règle sur OUI, la barre d'état ne s'affiche pas et lorsque je le règle sur NON, la barre d'état s'affiche. Alors veuillez me dire que je me trompe avec le concept ou quoi?
Nayan
1
Je pense parce que prendre la couleur semi-transparente par défaut définie dans didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' et définir dans plist View l'apparence de la barre d'état basée sur le contrôleur OUI
Darshit Shah
Merci beaucoup! Aussi, juste pour souligner que les documents Apple recommandent de vérifier avec if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {}. À votre santé!
Joel Balmer
Merci beaucoup.Votre code est si utile pour nous.Veuillez expliquer la fonction viewWillLayoutSubviews.
user3182143
4

Pour masquer la barre d'état dans ios7, procédez comme suit:

Dans Xcode, allez dans le Resourcesdossier " " et ouvrez " (app name)-Info.plist file".

  • vérifier la View controller based status bar appearanceclé " " et définir sa valeur " NO"
  • vérifier la Status bar is initially hiddenclé " " et définir sa valeur " YES"

Si les clés ne sont pas là, vous pouvez l'ajouter en sélectionnant " information property list" en haut et en cliquant sur + icône

Mandeep Pasbola
la source
Lisez la question clairement, il n'a pas demandé de cacher totalement la barre d'état.
ShayanK
1
@AspersionCast: Il a demandé "Y a-t-il un moyen d'éviter cela?" et c'est l'un des moyens de l'éviter.
Mandeep Pasbola
3

Si vous utilisez xibs, une implémentation très simple consiste à encapsuler toutes les sous-vues dans une vue de conteneur avec des indicateurs de redimensionnement (que vous utiliserez déjà pour la compatibilité 3,5 "et 4") afin que la hiérarchie des vues ressemble à ceci

xib héritier

puis viewDidLoad, faites quelque chose comme ceci:

- (void)viewDidLoad
{
  [super viewDidLoad];
  // initializations
  if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
  {
    CGRect frame = containerView.frame;
    frame.origin.y += 20;
    frame.size.height -= 20;
    containerView.frame = frame;
  }
}

De cette façon, les pointes n'ont pas besoin d'être modifiées pour la compatibilité iOS 7. Si vous avez un arrière-plan, il peut être conservé à l'extérieur containerViewet le laisser couvrir tout l'écran.

tipycalFlow
la source
3

C'est tout ce qui est nécessaire pour supprimer la barre d'état. entrez la description de l'image ici

Tony
la source
2

Pour la barre de navigation:

Écrire ce code:

self.navigationController.navigationBar.translucent = NO;

vient de faire l'affaire pour moi.

Saru
la source
1

La réponse de Vincent edgeForExtendedLayout a fonctionné pour moi.

Ces macros aident à déterminer la version du système d'exploitation, ce qui facilite les choses

// 7.0 and above 
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) 

// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending) 

ajoutez ces macros au fichier prefix.pch de votre projet et peut être consulté n'importe où

if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
 //some iOS 7 stuff
 self.edgesForExtendedLayout = UIRectEdgeNone;
}

if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
 // some old iOS stuff
}
RamaKrishna Chunduri
la source
1
pour moi self.edgesForExtendedLayout = UIRectEdgeNone; ne fonctionne pas ... une raison pour laquelle?
Fahim Parkar
1

J'ai posté ma réponse à un autre message avec la même question avec celui-ci.

À partir du guide de transition Apple iOS7, https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1

Plus précisément automaticallyAdjustsScrollViewInsets=YESet set self.edgesForExtendedLayout = UIRectEdgeNonefonctionne pour moi quand je ne veux pas le chevauchement et que j'ai un tableviewcontroller.

Liangjun
la source
0

Si vous voulez que "Use Autolayout" soit activé à tout prix, placez le code suivant dans viewdidload.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
{
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.extendedLayoutIncludesOpaqueBars = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
}
Ali Shahid
la source
0

Ma barre d'état et ma barre de navigation se chevauchent après le retour de la vue paysage de YTPlayer. Voici ma solution après avoir essayé la version de @comonitos mais ne fonctionne pas sur mon iOS 8

- (void)fixNavigationBarPosition {
    if (self.navigationController) {
        CGRect frame = self.navigationController.navigationBar.frame;
        if (frame.origin.y != 20.f) {
            frame.origin.y = 20.f;
            self.navigationController.navigationBar.frame = frame;
        }
    }
}

Appelez simplement cette fonction chaque fois que vous souhaitez fixer la position de la barre de navigation. J'ai appelé YTPlayerViewDelegateplayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
John Pang
la source