iOS 7: la barra di stato si sovrappone alla visualizzazione


109

Ho un ViewControllerche si trova all'interno di a UINavigationcontroller, ma la navigationBar è nascosta. Quando eseguo l'app su iOS 7, la barra di stato viene visualizzata nella parte superiore della mia visualizzazione. c'è un modo per evitarlo?

Non voglio scrivere alcun codice specifico del sistema operativo.

Inserisci qui la descrizione dell'immagine

Ho provato a impostare View controller-based status bar appearancesu NO, ma il problema non è stato risolto.


Ho pubblicato la mia risposta per mostrare la barra di stato come iOS 6 in iOS 7 stackoverflow.com/questions/18294872/…
Desert Rose,

2
È necessario regolare anche l'origine y e il valore delta per gestire il problema della barra di stato Questo potrebbe aiutarti a stackoverflow.com/q/18980925/1545180
Ganapathy

Risposte:


95

Xcode 5 ha iOS 6/7 Deltasche è stato creato appositamente per risolvere questo problema. Nello storyboard, ho spostato le mie visualizzazioni di 20 pixel verso il basso per guardare bene su iOS 7 e per renderlo compatibile con iOS 6, sono passato Delta ya -20.

inserisci qui la descrizione dell'immagine

Poiché il mio storyboard non utilizza il layout automatico, per ridimensionare correttamente l'altezza delle visualizzazioni su iOS 6 ho dovuto impostare Delta heightanche Delta Y.


8
la tua risposta è corretta ma non funziona con il display da 4 ". Aggiorna la tua risposta se riesci a farlo funzionare anche con il display da 4". Grazie in anticipo.

2
@AnkitMehta Non dovevo fare nulla di specifico per iPhone 4 "
aryaxt

5
ha funzionato per me. Si noti che per visualizzare questi delta, è necessario deselezionare "Usa layout automatico" in "Identità e tipo" per lo storyboard.
Marsant

2
Ho scoperto che oltre a impostare un -20 per ∆Y, ho dovuto anche impostare un +20 per ∆Height
Toland Hon

3
Cosa succede quando l'altezza della barra di stato cambia? F.ex .: quando l'utente attiva l'hot-spot, ecc ... l'altezza è di 40px ...
Lukasz

69

Se semplicemente NON vuoi alcuna barra di stato, devi aggiornare il tuo plist con questi dati: per fare ciò, nel plist, aggiungi queste 2 impostazioni:

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

In iOS 7 devi progettare la tua app tenendo presente una barra di stato trasparente sovrapposta. Vedi ad esempio la nuova app iOS 7 Weather.


3
Questa è in realtà l'unica buona risposta poiché risolve il problema nel suo nucleo nel modo in cui doveva essere fatto. Quindi: sono necessari voti positivi!
undici59

5
Potrebbe essere appropriato per alcune situazioni, ma devi stare molto attento a nascondere la barra di stato. Solo per visualizzazioni che sono giustificatamente a schermo intero, come lettori multimediali o visualizzatori di immagini.
smileBot

1
@ eleven59, intendi il modo in cui intendono gli autocrati di Apple.
JohnK

1
Sicuramente in questo modo meglio che cambiare l'offset di un controller di visualizzazione (che sembra davvero sporco).
Benjamin Oman,

nascondere la barra di stato non è una buona idea ... So che questo è il modo più semplice per gestire iOS 7, ma è NECESSARIO il tempismo ...
Fahim Parkar

43

Questo è il comportamento predefinito per UIViewControlleriOS 7. La visualizzazione sarà a schermo intero, il che significa che la barra di stato coprirà la parte superiore della visualizzazione.

Se hai un UIViewControllerall'interno di a UINavigationControllere la navigationBar è visibile, puoi avere il seguente codice nel tuo viewDidLoado avere un'immagine di sfondo per navigationBar fare il trucco.

self.edgesForExtendedLayout = UIRectEdgeNone;

Se hai navigationBar nascosto, devi regolare tutti gli elementi UIView spostando 20 punti. Non vedo altre soluzioni. Usare il layout automatico ti aiuterà un po '.

Ecco il codice di esempio per il rilevamento della versione iOS, se desideri la compatibilità con le versioni precedenti.

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;
}

18
Invece di recuperare, analizzare e confrontare la versione del sistema, si consiglia di utilizzareif ([self respondsToSelector:@selector(edgesForExtendedLayout)])
Sebastian Hojas

15

L'unica soluzione funzionante che ho creato da solo.

Ecco la mia sottoclasse UIViewController https://github.com/comonitos/ios7_overlaping

1 sottoclasse da UIViewController

2 Sottoclasse il tuo window.rootViewController da quella classe.

3 Voilà!

- (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 Aggiungere questo per rendere bianca la barra di stato Subito dopo [self.window makeKeyAndVisible]; !!!

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

ma questo non mostra l'ora in alto ... Il più grande svantaggio ... :(
Fahim Parkar

Funziona alla grande, ma per il passaggio 4 dovresti usare preferredStatusBarStyle nel tuo controller di visualizzazione, poiché setStatusBarStyle è deprecato e l'azione predefinita è non fare nulla. 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);
    }
  }
}

Aggiungi chiave in plist --- Visualizza l'aspetto della barra di stato basata sul controller: NO


cambiare il colore della finestra se necessario
Darshit Shah

Grazie, ha risolto il mio problema di sovrapposizione. Ma c'è ancora un problema: Visualizza l'aspetto della barra di stato basata sul controller: NO è quello di nascondere la barra di stato, immagino. Ma quando lo imposto su SÌ, non mostra la barra di stato e quando lo imposto su NO allora mostra la barra di stato. Quindi per favore dimmi che ho sbagliato con il concetto o cosa?
Nayan

1
Penso perché prendi il colore semi trasparente predefinito impostato in didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' e impostato in plist Visualizza l'aspetto della barra di stato basato sul controller SÌ
Darshit Shah

Bene grazie! Inoltre, solo per sottolineare che i documenti Apple consigliano di controllare con if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {}. Saluti!
Joel Balmer

Grazie mille.Il tuo codice è così utile per noi.Si prega di spiegare la funzione viewWillLayoutSubviews.
user3182143

4

Per nascondere la barra di stato in iOS7 segui questi semplici passaggi:

In Xcode vai alla Resourcescartella " " e apri " (app name)-Info.plist file".

  • controlla la View controller based status bar appearancechiave " " e imposta il suo valore " NO"
  • controlla la Status bar is initially hiddenchiave " " e imposta il suo valore " YES"

Se le chiavi non sono presenti, puoi aggiungerle selezionando " information property list" in alto e facendo clic sull'icona +


Leggi chiaramente la domanda, non ha chiesto di nascondere completamente la barra di stato.
ShayanK

1
@AspersionCast: Ha chiesto "C'è un modo per evitarlo?" e questo è uno dei modi per evitarlo.
Mandeep Pasbola


3

Se usi xibs, un'implementazione molto sempliceèincapsulare tutte le sottoviste all'interno di una vista contenitore con indicatori di ridimensionamento (che utilizzerai già per la compatibilità da 3,5 "e 4") in modo che la gerarchia della vista sia simile a questa

xib gerarchia

e poi viewDidLoad, fai qualcosa del genere:

- (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;
  }
}

In questo modo, i pennini non devono essere modificati per la compatibilità con iOS 7. Se hai uno sfondo, puoi tenerlo fuori containerViewe lasciarlo coprire l'intero schermo.


3

Questo è tutto ciò che serve per rimuovere la barra di stato. inserisci qui la descrizione dell'immagine


2

Per la barra di navigazione:

Scrivendo questo codice:

self.navigationController.navigationBar.translucent = NO;

ha appena fatto il trucco per me.


1

La risposta di Vincent edgeForExtendedLayout ha funzionato per me.

Queste macro aiutano a determinare la versione del sistema operativo rendendolo più semplice

// 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) 

aggiungi queste macro al file prefix.pch del tuo progetto e puoi accedervi ovunque

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
}

1
per me self.edgesForExtendedLayout = UIRectEdgeNone; non funziona ... qualsiasi motivo per cui?
Fahim Parkar

1

Ho pubblicato la mia risposta a un altro post con la stessa domanda con questo.

Dalla Guida alla transizione di Apple iOS7, https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1

In particolare automaticallyAdjustsScrollViewInsets=YESe set self.edgesForExtendedLayout = UIRectEdgeNonefunziona per me quando non voglio la sovrapposizione e ho un file tableviewcontroller.


0

Se si desidera che "Usa layout automatico" sia abilitato a qualsiasi costo, inserire il codice seguente in viewdidload.

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

0

La barra di stato e la barra di navigazione si sovrappongono dopo il ritorno dalla visualizzazione orizzontale di YTPlayer. Ecco la mia soluzione dopo aver provato la versione di @comonitos ma non funziona sul mio 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;
        }
    }
}

Basta chiamare questa funzione ogni volta che si desidera correggere la posizione della barra di navigazione. Ho chiamato su YTPlayerViewDelegateplayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.