La barra di stato di iOS 7 torna allo stile predefinito di iOS 6 nell'app per iPhone?


292

In iOS 7 il UIStatusBarè stato progettato in modo da fondersi con la vista in questo modo:

GUI progettata da Tina Tavčar (GUI progettata da Tina Tavčar )

  • È interessante, ma in qualche modo confonderà la tua vista quando hai qualcosa nella parte superiore della vista e si sovrappone alla barra di stato.

  • Esiste una soluzione semplice (come impostare una proprietà in info.plist) che può cambiare il modo in cui funziona [non sovrapponendosi] a com'è in iOS6?

  • So che una soluzione più semplice è quella di avere self.view.center.x+ 20 punti per ogni singolo controller di visualizzazione, ma cambiarli rovinerà altre dimensioni (avere un diverso self.view.center.xpuò causare problemi ai follower personalizzati, ecc.) E improvvisamente si trasforma in un lavoro noioso che è meglio evitare.

  • Sarò davvero felice se qualcuno mi può fornire una soluzione unica per questo.

PS So di poter nascondere la barra di stato facendo cose come avere

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

Nel didFinishLaunchingWithOptionsmetodo, ma questa è una soluzione alternativa, una scorciatoia per evitare il problema, quindi non considero una soluzione reale.


6
Le barre di stato purtroppo nere sono state deprecate in
iOS

Concordo con @GangstaGraham. Quei colori sono semplicemente meravigliosi ! Per rispondere alla tua domanda, temo che non puoi. Il motivo per cui la barra di stato è progettata in questo modo ora è perché la traslucenza è la nuova cosa di iOS ed è progettata per dare "profondità" a un'applicazione dicendo che è in cima a qualcosa, quindi c'è qualcosa sotto.
Cole Johnson,

Hai provato a impostare favoriteStatusBarStyle su UIStatusBarDefault? Acquista iOS 7 UIViewController Documentazione
theaob

1
Avere UIStatusBarDefaultper la barra di stato rende solo il suo contenuto di colore nero. Non ripristinerà il modo in cui funziona in iOS6.
吖 奇 说 - 何魏奇 Archy Will Ha il

2
Qualche fortuna con questo? Adoro iOS7 ma questa cosa mi sta facendo impazzire!
Mihai Fratu,

Risposte:


449

Questo è un post incrociato da un post sul blog che ho scritto , ma ecco il riassunto completo su barre di stato, barre di navigazione e controller di visualizzazione contenitore su iOS 7:

  1. Non è possibile preservare il layout della barra di stato in stile iOS 6. La barra di stato si sovrapporrà sempre alla tua applicazione su iOS 7

  2. Non confondere l'aspetto della barra di stato con il layout della barra di stato. L'aspetto (chiaro o predefinito) non influisce sulla disposizione della barra di stato (cornice / altezza / sovrapposizione). È anche importante notare che la barra di stato del sistema non ha più alcun colore di sfondo. Quando l'API fa riferimento a UIStatusBarStyleLightContent, significano testo bianco su uno sfondo chiaro. UIStatusBarStyleDefault è un testo nero su uno sfondo chiaro.

  3. L'aspetto della barra di stato è controllato lungo uno dei due percorsi di base reciprocamente esclusivi: è possibile impostarli programmaticamente nel modo tradizionale oppure UIKit aggiornerà l'aspetto per te in base ad alcune nuove proprietà di UIViewController. Quest'ultima opzione è attiva per impostazione predefinita. Controlla il valore plist della tua app per “Aspetto della barra di stato basata su ViewController” per vedere quale stai usando. Se imposti questo valore su SÌ, ogni controller di visualizzazione di livello superiore nella tua app (diverso da un controller di visualizzazione contenitore UIKit standard) deve sovrascrivere loStatusBarStyle preferito, restituendo lo stile predefinito o leggero. Se si modifica il valore di plist su NO, è possibile gestire l'aspetto della barra di stato utilizzando i familiari metodi UIApplication.

  4. UINavigationController modificherà l'altezza della sua UINavigationBar a 44 punti o 64 punti, a seconda di una serie di vincoli piuttosto strani e non documentati. Se UINavigationController rileva che la parte superiore del riquadro della vista è visivamente contigua alla parte superiore della sua UIWindow, disegna la barra di navigazione con un'altezza di 64 punti. Se la parte superiore della vista non è contigua alla parte superiore della UIWindow (anche se disattivata di un solo punto), disegna la barra di navigazione in modo "tradizionale" con un'altezza di 44 punti. Questa logica viene eseguita da UINavigationController anche se all'interno della gerarchia del controller di visualizzazione dell'applicazione sono presenti diversi elementi secondari. Non c'è modo di prevenire questo comportamento.

  5. Se si fornisce un'immagine di sfondo della barra di navigazione personalizzata che è alta solo 44 punti (88 pixel) e i limiti della vista di UINavigationController corrispondono ai limiti della finestra di UIWindow (come discusso nel n. 4), UINavigationController disegna l'immagine nel riquadro (0,20,320 , 44), lasciando 20 punti di spazio nero opaco sopra l'immagine personalizzata. Questo potrebbe confonderti nel pensare che sei uno sviluppatore intelligente che ha ignorato la regola n. 1, ma ti sbagli. La barra di navigazione è ancora alta 64 punti. L'incorporazione di un UINavigationController in una gerarchia di viste stile slide-to-rivela lo rende ampiamente chiaro.

  6. Fai attenzione alla proprietà delimitata in modo confuso da edgeForExtendedLayout di UIViewController. Regolazione dei bordi: ForExtendedLayout non fa nulla nella maggior parte dei casi. L'unico modo in cui UIKit utilizza questa proprietà è se aggiungi un controller di visualizzazione a un UINavigationController, quindi UINavigationController utilizza edgeForExtendedLayout per determinare se il suo controller di visualizzazione figlio deve essere visibile sotto l'area della barra di navigazione / barra di stato. L'impostazione di edgeForExtendedLayout su UINavigationController non fa nulla per modificare se UINavigationController ha un'area della barra di navigazione alta 44 o 64 punti. Vedi # 4 per quella logica. Una logica di layout simile si applica alla parte inferiore della vista quando si utilizza una barra degli strumenti o UITabBarController.

  7. Se tutto ciò che stai cercando di fare è impedire al tuo controller di visualizzazione figlio personalizzato di sovrapporre la barra di navigazione all'interno di un UINavigationController, quindi imposta edgeForExtendedLayout su UIRectEdgeNone (o almeno una maschera che esclude UIRectEdgeTop). Impostare questo valore il prima possibile nel ciclo di vita del controller della vista.

  8. UINavigationController e UITabBarController proveranno anche a riempire il contenutoInset di viste di tabella e viste di raccolta nella sua gerarchia di viste secondarie. Lo fa in un modo simile alla logica della barra di stato da # 4. Esiste un modo programmatico per impedirlo, impostando automaticamente AdjustsScrollViewInsets su NO per le viste della tabella e della raccolta (l'impostazione predefinita è SÌ). Ciò ha comportato alcuni seri problemi per Whisper e Riposte, poiché utilizziamo le regolazioni contentInset per controllare il layout delle viste della tabella in risposta ai movimenti della barra degli strumenti e della tastiera.

  9. Per ribadire: non è possibile tornare alla logica del layout della barra di stato in stile iOS 6. Per approssimare ciò, devi spostare tutti i controller di visualizzazione della tua app in una vista contenitore che è spostata di 20 punti dalla parte superiore dello schermo, lasciando una vista intenzionalmente nera dietro la barra di stato per simulare il vecchio aspetto. Questo è il metodo che abbiamo finito con Riposte e Whisper.

  10. Apple sta spingendo molto per assicurarsi di non provare a fare il n. 9. Vogliono che ridisegniamo tutte le nostre app in modo che si sovrappongano alla barra di stato. Ci sono molti argomenti convincenti, tuttavia, sia per l'esperienza utente che per motivi tecnici, perché questa non è sempre una buona idea. Dovresti fare ciò che è meglio per i tuoi utenti e non semplicemente seguire i capricci della piattaforma.


35
Volevo solo aggiungere che puoi aggiungere un vincolo a tutto ciò che si trova nella parte superiore della vista per essere allegato alla guida di layout superiore - questo lascerà uno spazio vuoto dietro la barra di stato (che puoi riempire con qualsiasi colore desideri) ma consentirà anche alla vista di adattarsi automaticamente alla posizione corretta anche in iOS 6. In questo modo non è necessario regolare manualmente la posizione delle visualizzazioni nel codice.
BreadicalMD,

4
Questa è una soluzione geniale. Hai esposto la mia ignoranza su AutoLayout. Meglio farlo.
Jaredsinclair,

1
Se si posiziona lo spazio superiore dell'oggetto sotto il bordo della guida di layout superiore, è possibile utilizzare il controllo di vincolo per aggiungere un vincolo di spaziatura verticale al vicino più vicino, che sarà ora la guida di layout superiore. In alternativa puoi usare ctrl + clic dal tuo oggetto nella guida di layout superiore per aggiungere esplicitamente un vincolo di spaziatura verticale.
BreadicalMD,

2
@BreadicalMD Una parte che non capisco è che -topLayoutGuide non è disponibile su iOS 6, quindi significa che devi usare diversi vincoli di Auto Layout su iOS 7 e 6?
Jeremy,

1
Ottima risposta ... Ma ho un dubbio 1) UINavigationController modifica l'altezza. Per favore, spiegalo un po 'di più. grazie
user1010819

122

Aggiornamenti del 19 settembre 2013:

corretti bug di ridimensionamento aggiungendo self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);

errori di battitura corretti nella NSNotificationCenterdichiarazione


Aggiornamenti del 12 settembre 2013:

corretto UIViewControllerBasedStatusBarAppearanceaNO

aggiunta una soluzione per app con rotazione dello schermo

aggiunto un approccio per cambiare il colore di sfondo della barra di stato.


Apparentemente, non c'è modo di ripristinare la barra di stato di iOS7 su come funziona in iOS6.

Tuttavia, possiamo sempre scrivere alcuni codici e trasformare la barra di stato in stile iOS6, e questo è il modo più breve che posso trovare:

  1. Impostato UIViewControllerBasedStatusBarAppearancesu NOin info.plist(per disattivare la visualizzazione dei controller di visualizzazione per regolare lo stile della barra di stato in modo da poter impostare lo stile della barra di stato utilizzando il metodo UIApplicationstatusBarStyle.)

  2. In AppDelegate's application:didFinishLaunchingWithOptions, chiama

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        [application setStatusBarStyle:UIStatusBarStyleLightContent];
        self.window.clipsToBounds =YES;
        self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
    
        //Added on 19th Sep 2013
        self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
    }
    return YES;
    


in modo da:

  1. Controlla se è iOS 7.

  2. Imposta il contenuto della barra di stato su bianco, anziché su UIStatusBarStyleDefault.

  3. Evita che vengano visualizzate le viste secondarie i cui frame si estendono oltre i limiti visibili (per le viste che si animano nella vista principale dall'alto).

  4. Crea l'illusione che la barra di stato occupi spazio come in iOS 6 spostando e ridimensionando il riquadro della finestra dell'app.


Per le app con rotazione dello schermo,

utilizzare NSNotificationCenter per rilevare le modifiche all'orientamento aggiungendo

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];

in if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)e creare un nuovo metodo in AppDelegate:

- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
    int a = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
    int w = [[UIScreen mainScreen] bounds].size.width;
    int h = [[UIScreen mainScreen] bounds].size.height;
    switch(a){
        case 4:
            self.window.frame =  CGRectMake(0,20,w,h);
            break;
        case 3:
            self.window.frame =  CGRectMake(-20,0,w-20,h+20);
            break;
        case 2:
            self.window.frame =  CGRectMake(0,-20,w,h);
            break;
        case 1:
           self.window.frame =  CGRectMake(20,0,w-20,h+20);
    }
}

In tal modo, quando l'orientamento cambia, attiverà un'istruzione switch per rilevare l'orientamento dello schermo dell'app (Ritratto, Upside-down, Orizzontale a sinistra o Orizzontale a destra) e modificare rispettivamente il riquadro della finestra dell'app per creare l'illusione della barra di stato di iOS 6.


Per modificare il colore di sfondo della barra di stato:

Inserisci

 @property (retain, nonatomic) UIWindow *background;

in AppDelegate.hper fare backgrounduna proprietà nella classe e impedire ARC da deallocando esso. (Non è necessario farlo se non si utilizza ARC.)

Dopodiché devi solo creare la UIWindow in if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1):

background = [[UIWindow alloc] initWithFrame: CGRectMake(0, 0, self.window.frame.size.width, 20)];
background.backgroundColor =[UIColor redColor];
[background setHidden:NO];

Non dimenticare di @synthesize background;dopo @implementation AppDelegate!


3
Questo si interrompe in rotazione. solo un
avvertimento

2
@JesseNaugher Raccomando di modificare il vincolo di spaziatura verticale da 0 a 20 a livello di programmazione. Funzionerà sulla rotazione.
esperto

2
Qualche idea su come possiamo evitare che la barra di navigazione si espanda di 20 pixel? Questa soluzione va bene per me, ma la mia barra di navigazione è troppo alta di 20 pixel.
simonbs,

4
@ArchyHolt: la tua soluzione semplice funziona per me tranne quando presento un controller di visualizzazione modale. Una volta eliminato il controller della vista modale, la vista rimanente si trova ora sotto la barra di stato. L'ho riprodotto in un nuovo progetto di esempio per assicurarmi che non ci sia nient'altro di strano. Penso che forse la tua soluzione più avanzata possa essere utile qui, ma non sono sicuro di quale notifica entrerebbe in gioco. Qualche idea?
markdorison,

4
La vista si ripristina dopo aver eliminato un controller di vista modale. :(
KarenAnne,

41

AGGIORNAMENTO (NUOVA SOLUZIONE)

Questo aggiornamento è la migliore soluzione al problema della barra di navigazione di iOS 7. Puoi impostare un esempio di colore della barra di navigazione: FakeNavBar.backgroundColor = [UIColor redColor];

Nota: se si utilizza il controller di navigazione predefinito, utilizzare la soluzione precedente.

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
    {
        UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
        FakeNavBar.backgroundColor = [UIColor whiteColor];

        float navBarHeight = 20.0;
        for (UIView *subView in self.window.subviews) {

            if ([subView isKindOfClass:[UIScrollView class]]) {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
            } else {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
            }
        }
        [self.window addSubview:FakeNavBar];
    }

    return YES;

}

VECCHIA SOLUZIONE - SE usi il codice precedente, ignora il codice e l'immagine seguenti

Questa è la vecchia versione della soluzione della barra di navigazione di iOS 7.

Ho risolto il problema con il seguente codice. Questo serve per aggiungere una barra di stato. didFinishLaunchingWithOptions

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    UIView *addStatusBar = [[UIView alloc] init];
    addStatusBar.frame = CGRectMake(0, 0, 320, 20);
    addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
    [self.window.rootViewController.view addSubview:addStatusBar];
}

E per Interface Builder questo è per quando si apre con iOS 6; sta iniziando da 0 pixel.

Nota: i delta di iOS 6/7 vengono visualizzati solo se si deseleziona "Usa autolayout" per il controller di visualizzazione in "Impostazioni file" (icona più a sinistra) nel riquadro dei dettagli.

Inserisci qui la descrizione dell'immagine


6
Mi hai reso felice, prendi +1 per l'aiuto!
Niru Mukund Shah,

5
Nota: i delta di iOS 6/7 vengono visualizzati solo se si deseleziona "Usa autolayout" per il controller di visualizzazione in "Impostazioni file" (icona più a sinistra) nel riquadro dei dettagli.
Matt,

1
Molte grazie! Mi hai risparmiato un sacco di problemi!
Neowinston,

2
Chi ha detto che il layout della barra di stato in stile iOS 6 non può essere mantenuto, puoi farlo in modo @ TacettinÖzbölük ... grazie amico per questa soluzione awsum.
Vizllx,

1
Ben fatto! inoltre, solo per notare che Apple lo preferisce ora: if (NSFoundationVersionNumber> = NSFoundationVersionNumber_iOS_6_1) {}
Joel Balmer,

26

SOLUZIONE:

Impostalo nel tuo viewcontroller o nel rootviewcontroller sovrascrivendo il metodo:

-(BOOL) prefersStatusBarHidden
    {
        return YES;
    }

Non è una cattiva soluzione. Rimuovere completamente la barra. Potrebbe non essere ideale per UX per tutto il tempo ma praticabile.
Farhan Hafeez,

Semplicemente fantastico. Ha funzionato perfettamente per me.
madLokesh,

Scenario: una volta che torno al mio UIVIew dopo aver riprodotto il video a schermo intero, in basso appare una barra nera che ha le dimensioni della barra di stato, sebbene stia già utilizzando una barra di stato. Ho rimosso del tutto la barra di stato e ora il problema è stato risolto.
madLokesh,

Ho solo avuto successo usando questo metodo
user2277872

17

Ecco un altro approccio per i progetti che fanno ampio uso dello Storyboard:

OBBIETTIVO:

Lo scopo di questo approccio è ricreare lo stesso stile della barra di stato in iOS7 rispetto a iOS6 (vedi il titolo della domanda "Barra di stato iOS 7 Torna allo stile iOS 6?").

SOMMARIO:

Per raggiungere questo obiettivo, utilizziamo lo Storyboard il più possibile spostando verso il basso gli elementi dell'interfaccia utente che sono sovrapposti dalla barra di stato (sotto iOS 7), mentre utilizziamo i delta per annullare la modifica del layout verso il basso per iOS 6.1 o precedenti. Lo spazio aggiuntivo risultante in iOS 7 viene quindi occupato da un UIView con backgroundColor impostato su un colore di nostra scelta. Quest'ultimo può essere creato in codice o utilizzando lo Storyboard (vedi ALTERNATIVE di seguito)

IPOTESI:

Per ottenere il risultato desiderato seguendo i passaggi seguenti, si presume che View controller-based status bar appearancesia impostato su NO e che Status bar stylesia impostato su "Stile nero trasparente (alfa di 0,5)" o "Stile nero opaco". Entrambe le impostazioni sono disponibili / o aggiunte in "Informazioni" nelle impostazioni del progetto.

STEPS:

  • Aggiungi una sottoview alla UIWindow come sfondo della barra di stato. Per ottenere ciò, aggiungi quanto segue al tuo AppDelegate application: didFinishLaunchingWithOptions:dopomakeKeyAndVisible

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        UIView *statusBarBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, yourAppsUIWindow.frame.size.width, 20)];
        statusBarBackgroundView.backgroundColor = [UIColor blackColor];
        [yourAppsUIWindow addSubview:statusBarBackgroundView];
    }
    
  • Dal momento che hai aggiunto a livello di programmazione uno sfondo SOLO per iOS 7, dovrai regolare il layout degli elementi dell'interfaccia utente che sono sovrapposti di conseguenza dalla barra di stato, preservandone il layout per iOS6. A tale scopo, procedi come segue:

    • Assicurati che Use Autolayoutsia deselezionato per il tuo Storyboard (questo perché altrimenti "iOS 6/7 Delta" non viene mostrato nella finestra di ispezione Dimensioni). Per fare questo:
      • seleziona il tuo file Storyboard
      • mostra Utilità
      • seleziona "Mostra Impostazioni File"
      • In "Documento Interface Builder" deseleziona "Usa autolayout"
    • Facoltativamente, per aiutarti a monitorare le modifiche al layout sia per iOS 7 che per 6 mentre le applichi, seleziona "Assistant Editor", seleziona "Anteprima" e "iOS 6.1 o precedente": inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine
    • Ora seleziona l'elemento dell'interfaccia utente che desideri regolare in modo che non sia più sovrapposto dalla barra di stato
    • Seleziona "Mostra Impostazioni dimensioni" nella colonna Utilità
    • Riposiziona l'elemento dell'interfaccia utente lungo l'asse Y della stessa quantità dell'altezza della barra di stato bg: inserisci qui la descrizione dell'immagine
    • E modifica il valore delta iOS6 / 7 per Y della stessa quantità NEGATIVA dell'altezza della barra di stato bg (nota la modifica nell'anteprima di iOS 6 se la stai usando): inserisci qui la descrizione dell'immagine

ALTERNATIVE:

Per aggiungere ancora meno codice nei progetti pesanti dello storyboard e fare in modo che lo sfondo della barra di stato si autoroteri, invece di aggiungere programmaticamente uno sfondo per la barra di stato, è possibile aggiungere una vista colorata a ciascun controller di vista che si trova nella parte superiore della vista principale di detto viewcontroller. Dovresti quindi modificare l'alta delta di questa nuova vista con la stessa quantità negativa dell'altezza della tua vista (per farla scomparire sotto iOS 6).

Il rovescio della medaglia di questa alternativa (anche se forse trascurabile se si considera la compatibilità con autorotazione) è il fatto che questa vista extra non è immediatamente visibile se si sta visualizzando lo Storyboard per iOS 6. Sapresti che è lì solo se guardassi " Struttura del documento "dello Storyboard.


12

Se non desideri che i controller della vista vengano sovrapposti dalla barra di stato (e dalle barre di navigazione), deseleziona la casella "Estendi bordi sotto le barre superiori" in Interface Builder in Xcode 5.

Deseleziona i bordi estesi sotto le barre superiori


7
Questo è possibile solo se usi uno storyboard
Cœur

3
Funziona solo con contenitori vcs come controller di navigazione o controller tabbar
Andrea

2
edgeForExtendedLayout viene utilizzato solo dai controller di visualizzazione contenitore (come UINavigationController) per determinare se le viste dei propri figli devono essere sovrapposte dal chrome del genitore. L'impostazione di questa proprietà sul controller della vista principale per UIWindow non ha effetto. Vedere la mia risposta di cui sopra: stackoverflow.com/questions/18294872/...
jaredsinclair

Come si fa per un UITabBarController @Andrea? Grazie.
KarenAnne,

@KarenAnne Dipende se lo fai programmaticamente o con storyboard. A livello di programmazione, è sufficiente impostare la proprietà edgeForExtent su ciò che ti piace nel controller di visualizzazione che stai mostrando all'interno di UITabBarViewController, ma per non avere il problema della barra di stato devi caricare un controller di navigazione all'interno di UITabbarController. Controlla qui developer.apple.com/library/ios/documentation/UserExperience/…
Andrea

11

Apple ha rilasciato domande e risposte tecniche QA1797: Impedire alla barra di stato di coprire le visualizzazioni . Funziona bene per le versioni iOS 6 e iOS 7.


5
Apple suppone che tutti stiano usando il layout automatico. Il layout automatico è stato orribile in Xcode 4 e Xcode 5 è stato appena rilasciato, quindi questo è un presupposto dubbio.
Glenn Maynard,

1
Ma in prospettiva questa è una soluzione migliore quindi ridimensionare il frame della finestra principale o della barra di stato.
Igor,

Per quanto ne so, la soluzione di Apple non funziona se il rootViewController è un splitViewController.
Vern Jensen,

8

Ho visto molti molti molti molti tutorial per risolvere questo maledetto problema. Ma nessuno di loro funziona! Ecco la mia soluzione e funziona per me:

if( [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f ) {
    float statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
    for( UIView *v in [self.view subviews] ) {
        CGRect rect = v.frame;
        rect.origin.y += statusBarHeight;
        v.frame = rect;
    }
}

La logica è semplice Sposto tutte le visualizzazioni dei bambini su self.view con 20 pixel. È tutto. Quindi, lo screenshot verrà visualizzato proprio come ha fatto iOS 6. Odio la barra di stato di iOS7! ~ "~


2
dove dovrei aggiungere questo? nel delegato dell'app è stato avviato con le opzioni?
mhmdshawqi,

Quando lo faccio, la mia barra di stato diventa bianca
ropo

6

Una piccola alternativa alla risposta di Archy Holt, un po 'più semplice:

un. Impostato UIViewControllerBasedStatusBarAppearancesu NOin info.plist

b. In AppDelegate's application:didFinishLaunchingWithOptions:, chiamata:

if ([[UIDevice currentDevice].systemVersion floatValue] < 7)
{
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
else
{
    // handling statusBar (iOS7)
    application.statusBarStyle = UIStatusBarStyleLightContent;
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
    self.window.clipsToBounds = YES;

    // handling screen rotations for statusBar (iOS7)
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}

E aggiungi il metodo:

- (void)applicationDidChangeStatusBarOrientationNotification:(NSNotification *)notification
{
    // handling statusBar (iOS7)
    self.window.frame = [UIScreen mainScreen].applicationFrame;
}

Puoi anche prendere in considerazione la sottoclasse UIWindowper gestirla UIApplicationDidChangeStatusBarOrientationNotification.


hai problemi con presentViewController: animato: completamento:?
Tùng Đỗ

@TùngĐỗ vero, quindi ho fatto un'alternativa che funziona meglio: stackoverflow.com/questions/18294872/…
Cœur

5

L'ho usato in tutti i miei controller di visualizzazione, è semplice. Aggiungi queste righe in tutti i metodi viewDidLoad:

- (void)viewDidLoad{
    //add this 2 lines:
    if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

    [super viewDidLoad];
}

1
Ha funzionato come un incantesimo e morto facilmente. In ruby ​​motion, prima della chiamata al superuso: self.edgesForExtendedLayout = UIRectEdgeNone se risponde a ToSelector ("edgeForExtendedLayout")
tehprofessor

4

Prova questo semplice metodo ....

Passaggio 1 : cambiare in singoloviewController

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];

Passaggio 2 : modificare nell'intera applicazione

info.plist
      ----> Status Bar Style
                  --->UIStatusBarStyle to UIStatusBarStyleBlackOpaque

Passaggio 3 : aggiungere anche questo in ciascuno viewWillAppearper regolare l' statusbaraltezza periOS7

    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 7) {
        CGRect frame = [UIScreen mainScreen].bounds;
        frame.origin.y+=20.0;
        frame.size.height-= 20.0;
        self.view.frame = frame;
        [self.view layoutIfNeeded];
    }


3

Ho raggiunto la barra di stato come iOS 6 in iOS 7.

Impostare UIViewControllerBasedStatusBarAppearance su NO in info.plist

Inserisci questo codice nel - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptionsmetodo

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    [application setStatusBarStyle:UIStatusBarStyleLightContent];
    self.window.clipsToBounds =YES;
    self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height);

    //Added on 19th Sep 2013
    NSLog(@"%f",self.window.frame.size.height);
    self.window.bounds = CGRectMake(0,0, self.window.frame.size.width, self.window.frame.size.height);
}

Può ridurre di 20 pixel tutte le visualizzazioni. Per finire, usa il seguente codice nel -(void)viewDidAppear:(BOOL)animatedmetodo

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    CGRect frame=self.view.frame;
    if (frame.size.height==[[NSUserDefaults standardUserDefaults] floatForKey:@"windowHeight"])
    {
        frame.size.height-=20;
    }
    self.view.frame=frame;
}

Devi impostare il valore di WindowHeight Userdefaults dopo l'allocazione della finestra in Metodo didFinishLauncing come

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[NSUserDefaults standardUserDefaults] setFloat:self.window.frame.size.height forKey:@"windowHeight"];

Un approccio migliore è rendere UINavigationBar heightuguale a 64 anziché a 44. Quindi la barra si estenderà fino in cima come nelle app di Apple.
Aaron Brager,

@AaronBrager Ma il mio requisito era mostrare la barra di stato in stile iOS 6.
Desert Rose

Potete per favore aggiungere la soluzione per orientamento orizzontale iOS 7 ?. Sto facendo la stessa cosa. ma non funziona in iOS 7 Landscape.
sathiamoorthy,

@DesertRose THX! Questo funziona per me, ma interrompe l'Uitabbar in basso. Ho un'app basata sul controller della barra delle schede con 3 visualizzazioni, 2 delle quali sono controller di visualizzazione tabella.
marciokoko,

1
FINO A quando ruoto il dispositivo (il mio dispositivo iOS 7 è un iPad), questo lo risolve perfettamente. Ma una volta ruotato, la barra nera rimane esattamente dove si trova e la "vista" (scusate se questo è il termine tecnico sbagliato, sono un PhoneGap / web guy) mantiene la sua altezza ridotta - tranne che non è più l'altezza, è la larghezza. Questa soluzione non supporta la rotazione ma è la soluzione migliore che abbia mai visto: come può essere migliorata per controllare le rotazioni del dispositivo? Grazie!
Tylerl,

2

Se stai usando Interface builder, prova questo:

Nel tuo file xib:

1) Seleziona la vista principale, imposta il colore di sfondo su nero (o qualsiasi colore desideri che sia la barra di stato

2) Assicurarsi che lo sfondo sia una sottoview autonoma posizionata come figlio di livello superiore della vista del controller.
Sposta lo sfondo per diventare un figlio diretto della vista del controller. Controlla il pannello di ridimensionamento automatico per essere sicuro di aver bloccato tutti i bordi del frame, attivato entrambi gli assi di flessibilità e, se si tratta di UIImageView, imposta la modalità del contenuto su Scala per riempire. A livello di programmazione, questo si traduce in contentMode impostato su UIViewContentModeScaleToFill e ha la maschera di ridimensionamento automatico impostata su (UIViewAutoresizingFLEXWidth | UIViewAutoresizingFLEXHeight).

3) Ora sposta tutto ciò che è bloccato in alto - in basso di 20 punti e imposta un delta Y di iOS 6/7 a -20.
Tutti i bambini di livello superiore che sono bloccati sul frame superiore nel pannello di ridimensionamento automatico devono essere spostati di 20 punti verso il basso e il loro delta Y iOS 6/7 impostato su -20. (Cmd selezionare tutti quelli e fare clic sulla freccia in giù 20 volte - c'è un modo migliore qualcuno?)

4) Regola l'altezza delta iOS 6/7 di tutti gli elementi di cui sopra con un'altezza flessibile. Tutti gli elementi che sono stati bloccati nella parte superiore e inferiore del frame e con altezza flessibile abilitata nel pannello di ridimensionamento automatico devono anche avere un'altezza delta iOS 6/7 impostata su 20. Ciò include la vista di sfondo sopra menzionata. Questo può sembrare anti-intuitivo, ma a causa dell'ordine in cui vengono applicati, è necessario. L'altezza del fotogramma viene prima impostata (in base al dispositivo), quindi vengono applicati i delta e infine le maschere di ridimensionamento automatico vengono applicate in base alle posizioni di offset di tutti i fotogrammi figlio: pensateci per un po ', avrà senso.

5) Infine, gli elementi che erano bloccati sul telaio inferiore ma non sul telaio superiore non necessitano affatto di delta.

Questo ti darà la barra di stato identica in iOS7 e iOS6.

D'altra parte, se si desidera lo stile iOS7 mantenendo la compatibilità con iOS6, impostare i valori di altezza delta Y / delta su 0 per la vista di sfondo.

Per vedere più informazioni sulla migrazione di iOS7 leggi il post completo: http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html


Nessun delta quando si utilizza il layout automatico
lostintranslation

2

La mia soluzione era quella di aggiungere un UIViewcon un'altezza di 20 punti nella parte superiore della finestra quando su iOS 7. Quindi ho creato un metodo nella mia classe AppDelegate per mostrare / nascondere lo sfondo "solido" della barra di stato. In application:didFinishLaunchingWithOptions::

// ...

// Add a status bar background
self.statusBarBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.bounds.size.width, 20.0f)];
self.statusBarBackground.backgroundColor = [UIColor blackColor];
self.statusBarBackground.alpha = 0.0;
self.statusBarBackground.userInteractionEnabled = NO;
self.statusBarBackground.layer.zPosition = 999; // Position its layer over all other views
[self.window addSubview:self.statusBarBackground];

// ...
return YES;

Quindi ho creato un metodo per sfumare in / out lo sfondo nero della barra di stato:

- (void) showSolidStatusBar:(BOOL) solidStatusBar
{
    [UIView animateWithDuration:0.3f animations:^{
        if(solidStatusBar)
        {
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
            self.statusBarBackground.alpha = 1.0f;
        }
        else
        {
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
            self.statusBarBackground.alpha = 0.0f;
        }
    }];
}

Tutto quello che devo fare ora è chiamare [appDelegate showSolidStatusBar:YES]se necessario.


2

Questo può essere un problema schiacciante se usi il layout automatico perché non puoi più manipolare direttamente i frame. C'è una soluzione semplice senza troppo lavoro.

Ho finito per scrivere un metodo di utilità in una classe di utilità e l'ho chiamato da tutti i viewDidLayoutSubviewsmetodi dei controller di visualizzazione .

+ (void)addStatusBarIfiOS7:(UIViewController *)vc
    {
        if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
            CGRect viewFrame = vc.view.frame;
            if(viewFrame.origin.y == 20) {
                //If the view's y origin is already 20 then don't move it down.
                return;
            }
            viewFrame.origin.y+=20.0;
            viewFrame.size.height-= 20.0;
            vc.view.frame = viewFrame;
            [vc.view layoutIfNeeded];
        }
    }

Sostituisci il tuo viewDidLayoutSubviewsmetodo nel controller di visualizzazione, dove vuoi la barra di stato. Ti farà superare il peso di Autolayout.

- (void)viewDidLayoutSubviews
{
    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    [super viewDidLayoutSubviews];
    [MyUtilityClass addStatusBarIfiOS7:self];
}

1

Il modo più semplice per farlo è installare un SDK più vecchio sul tuo Xcode più recente.

Come installare l'SDK precedente sul nuovo Xcode?

  1. Puoi ottenere l'SDK per iOS 6.1 da http://www.4shared.com/zip/NlPgsxz6/iPhoneOS61sdk.html o scaricare un Xcode più vecchio e ottenere l'SDK dal suo contenuto

  2. Decomprimi e incolla questa cartella in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs

  3. Riavvia l'xcode.

  4. Ora puoi selezionare un SDK più vecchio nelle impostazioni di creazione del tuo progetto

Spero che ti aiuti. Ha funzionato per me =)


ha funzionato per me. grazie @marcelosalloum ma sto ancora cercando una soluzione alternativa per la mia app phonegap (uiwebview) per supportare la barra di stato trasparente di iOS7 per il futuro aggiornamento della mia app. grazie ancora. ;)
hanism

@marcellosaloum, sei sicuro che l'app sarà accettata da Apple? Hanno detto che le app compilate con XCode 4 non sarebbero più accettate ... questo in realtà significa SDK per iOS 6.
Valerio,

La mia app è stata infatti accettata perché Xcode5 è in grado di compilare SDK iOS precedenti. Non sono sicuro se AppStore rifiuterà le app costruite Xcode4 ma (Xcode4! = IOS 6 SDK) come hai detto.
marcelosalloum,

È stato dopo il 1 febbraio? In quel giorno Apple lo ha reso obbligatorio.
Valerio,

No, lo scorso anno ho toccato quel codice, folk. Non sapevo che Apple lo avesse reso obbligatorio (non felice di sapere però). Per favore, pubblichi qui il link che lo dice? Saluti
marcelosalloum

1

Come usando il presentViewController:animated:completion:pasticciato window.rootViewController.view, ho dovuto trovare un approccio diverso a questo problema. Finalmente sono riuscito a funzionare con modali e rotazioni subclassando la UIView del mio rootViewController.

.h

@interface RootView : UIView

@end

.m

@implementation RootView

-(void)setFrame:(CGRect)frame
{
    if (self.superview && self.superview != self.window)
    {
        frame = self.superview.bounds;
        frame.origin.y += 20.f;
        frame.size.height -= 20.f;
    }
    else
    {
        frame = [UIScreen mainScreen].applicationFrame;
    }

    [super setFrame:frame];
}

- (void)layoutSubviews
{
    self.frame = self.frame;

    [super layoutSubviews];
}

@end

Ora hai una soluzione alternativa per le animazioni iOS7.


1

Sono in ritardo per questa risposta, ma voglio solo condividere ciò che ho fatto, che è sostanzialmente la soluzione più semplice

Prima di tutto-> Vai al tuo info.plistfile e aggiungi Stile barra di stato-> Stile nero trasparente (Alpha di 0,5)

Ora, eccolo qui: -

Aggiungi questo codice in AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
     //Whatever your code goes here
  if(kDeviceiPad){

     //adding status bar for IOS7 ipad
         if (IS_IOS7) {
              UIView *addStatusBar = [[UIView alloc] init];
              addStatusBar.frame = CGRectMake(0, 0, 1024, 20);
              addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //change this to match your navigation bar
              [self.window.rootViewController.view addSubview:addStatusBar];
                    }
                }
    else{

         //adding status bar for IOS7 iphone
        if (IS_IOS7) {
            UIView *addStatusBar = [[UIView alloc] init];
            addStatusBar.frame = CGRectMake(0, 0, 320, 20);
            addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //You can give your own color pattern
            [self.window.rootViewController.view addSubview:addStatusBar];
        }

    return YES;
   }

0

La mia soluzione molto semplice (supponendo che sia supportato solo l'orientamento verticale) è ridefinire i limiti della finestra dell'applicazione per le versioni iOS inferiori alla 7, nel metodo didFinishLaunchingWithOptions del delegato dell'app:

CGRect screenBounds = [[UIScreen mainScreen] bounds];
if ([HMService getIOSVersion] < 7) {
    // handling statusBar (iOS6) by leaving top 20px for statusbar.
    screenBounds.origin.y = 20;
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}
else {
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}

Il tuo codice sposta semplicemente 'y' da 0 a 20 ma non regola l'altezza di conseguenza, quindi dovresti aggiungere screenBounds.size.height - = 20; subito dopo screenBounds.origin.y = 20;
Amit C.,

0

Puoi nascondere la barra di stato tutti insieme. Quindi la tua app sarà a schermo intero. Penso che sia il meglio che otterrai.

UIStatusBarStyleNone o impostato nelle impostazioni di destinazione.


2
dove specificare UIStatusbarstylenone
user4951

0

Passaggi per Nascondi la barra di stato in iOS 7:

1. Vai al file info.plist dell'applicazione.

2.E impostare, Visualizza l'aspetto della barra di stato basata sul controller: NO booleano

Spero di aver risolto il problema della barra di stato .....


0

Per continuare a lavorare con setStatusBarHidden: utilizzo questa categoria:

@interface UIApplication (StatusBar)

-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden;

@end

@implementation UIApplication (StatusBar)

-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden{
    if (!IOS7) {
        [self setStatusBarHidden:statusBarHidden];
        return;
     }

    if ([self isStatusBarHidden] == statusBarHidden) {
        return;
    }

    [self setStatusBarHidden:statusBarHidden];
    [self keyWindow].clipsToBounds = YES;
    CGFloat offset = statusBarHidden ? 0 : 20;
    [self keyWindow].frame =  CGRectMake(0,offset,[self keyWindow].frame.size.width,[self keyWindow].frame.size.height-offset);
    [self keyWindow].bounds = CGRectMake(0, offset, [self keyWindow].frame.size.width,[self keyWindow].frame.size.height);
}

@end


0

Potrebbe essere troppo tardi per condividere, ma ho qualcosa da contribuire che potrebbe aiutare qualcuno, stavo cercando di sottoclassare la UINavigationBar e volevo far sembrare iOS 6 con la barra di stato nera e il testo della barra di stato in bianco.

Ecco cosa ho trovato lavorando per quello

        self.navigationController?.navigationBar.clipsToBounds = true
        self.navigationController?.navigationBar.translucent = false
        self.navigationController?.navigationBar.barStyle = .Black
        self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

Ha reso il mio sfondo della barra di stato nero, il testo della barra di stato bianco e il colore della barra di navigazione bianco.

iOS 9.3, XCode 7.3.1

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.