2010-08-21 18 views
12

Nella mia app, ho ottenuto un UINavigationController. Sfortunatamente, quando ruoto il dispositivo e l'orientamento dell'interfaccia cambia, UINavigationBar non cambia la sua altezza. In altre applicazioni iPhone, come Contacts.app, la barra di navigazione diventa leggermente meno alta in modalità orizzontale. Deve essere integrato, perché se si porta l'app di esempio di navigazione dal menu XCode e si aggiunge l'orientamento dell'interfaccia ad esso, cambia l'altezza della barra di navigazione correttamente.UINavigationBar autoresizing

Come si può ridimensionare la barra di spostamento come in tutte le altre app per iPhone che ho visto?

risposta

19

Ho fatto un po 'di test, e anche se non mi piace il metodo, è abbastanza facile da fare.

Dopo aver cercato un metodo privato che potrebbe aver funzionato, non sono riuscito a trovarne uno. Tutto quello che ho trovato era:

@property BOOL forceFullHeightInLandscape; 

- (BOOL)isMinibar; 

Non c'è setter per -isMinibar, quindi non possiamo impostare tale. Immagino che restituisca un valore basato sulla sua altezza. Inoltre, forceFullHeightInLandscape è stato impostato su NO, tuttavia non ha ancora regolato la sua altezza.

Mentre cambiare la autoresizingMask per includere UIViewAutoresizingFlexibleHeight, la vista fatto ridimensionamento ad essere più piccoli, ma ormai era troppo piccola. Tuttavia, -isMinibar restituito all'improvviso YES. Questo mi ha fatto pensare solo a ridimensionare la vista da sola, regolandola all'altezza giusta.

Così ci andiamo, un metodo che funziona, anche senza le chiamate alle API private:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    [self.navigationBar performSelector:@selector(sizeToFit) withObject:nil afterDelay:(0.5f * duration)]; 
} 

Una cosa che dovrete affrontare è che i punti di vista sotto la barra non otterranno regolato sulla barra più piccola, in modo che ci sia uno spazio tra la barra e le viste sottostanti. Il modo più semplice per risolverlo è aggiungere una vista container, proprio come nel caso di UINavigationController. Che saresti venuto con qualcosa di simile:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    [self performSelector:@selector(resizeViewsForNavigationBar) withObject:nil afterDelay:(0.5f * duration)]; 
} 

- (void)resizeViewsForNavigationBar { 
    [self.navigationBar sizeToFit]; 

    // Resize containerView accordingly. 
    CGRect containerViewRect = self.containerView.frame; 
    containerViewRect.origin.y = CGRectGetMaxY(self.navigationBar.frame); 
    containerViewRect.size.height = CGRectGetMaxY(self.view.frame) - containerViewRect.origin.y; 
    self.containerView.frame = containerViewRect; 
} 
+0

+1 per la risposta eccellente – vodkhang

+0

Grazie per la risposta, non posso testarlo adesso ma ti riporterò una volta che l'ho provato. È interessante notare che la vista del contenitore si ridimensiona già correttamente, come se la barra di navigazione fosse diventata più corta come dovrebbe. – ryyst

+0

L'ho provato proprio ora e funziona perfettamente! Poiché la vista del contenitore è già ridimensionata correttamente, ho solo bisogno della chiamata 'sizeToFit'. – ryyst

0

Penso che questo è una specie di simile a te e hanno il frammento di codice:

iPhone: UINavigationBar with buttons - adjust the height

+0

Sei sicuro l'altezza della barra di navigazione contrazione non è incorporato somehwere? – ryyst

+0

Deve essere integrato, perché se si porta l'app di esempio di navigazione dal menu XCode e si aggiunge l'orientamento dell'interfaccia ad esso, cambia l'altezza della barra di navigazione correttamente. – ryyst

2

Credo che il comportamento desideri solo accade quando si aggiunge un controller di navigazione (che rappresenta le barre (navigazione o della barra degli strumenti)), alla finestra nel delegato app o presentato da una barra delle linguette, ecc.

È possibile aggiungere una barra di navigazione tramite IB o codice, ma ciò non significa che si disponga di un controller di navigazione. La mia opinione è, creare un controller di navigazione e inizializzarlo con il controller della vista in cui si sta lavorando. Probabilmente quando la vista ruota, la barra di navigazione si restringerà un po ', nel modo che preferisci.

Spero che questo aiuti

+0

Questo è esattamente quello che ho fatto e no, non funziona. Grazie per la risposta però! – ryyst

0

Ho appena provato un paio di cose solo all'interno di Interface Builder e Xcode e fino a quando si utilizza il UINavigationBarController come RootViewController funziona come descritto - sempre più piccolo. Hai cambiato qualcosa all'interno del Controller stesso o in parti del modo in cui è stato caricato il Controller? Soprattutto per quanto riguarda il lancio di eventi? Ho avuto brutte esperienze con lo UITabBarController in termini di rottura della messaggistica corretta e alcuni effetti collaterali "interessanti" della vista. Solo una prova e una supposizione.

+0

Beh, in effetti sto usando anche un UITabBarController. Oltre a questo, sto creando tutto con il codice, senza Interface Builder. – ryyst

+0

Ah, ok, vedendo che è già stata risposta, sono curioso di sapere se si utilizza UITabBar in modo programmatico. Non funziona ancora? Presumo che sia tutto contenuto nel RootViewController. Forse non è davvero un bug ma non funziona correttamente con due controller. Se provi a farlo con Interface Builder non andrà comunque, non permettendo di confondere un NavigationBarController con un UITabBarController. – mic

1

Ho appena avuto anche questo errore, e anche se probabilmente non è per lo stesso motivo, mi piacerebbe postarlo qui per aiutare chiunque altro.

Se stai sovrascrivendo qualsiasi willRotateToInterface metodi, ricordarsi di chiamare super

ho cancellati su questo, ma una volta che ho visto la risposta accettata è venuto da me.

2

Grazie a Joost Ho aggiunto

@property BOOL forceFullHeightInLandscape; 

alla mia classe di UINavigationBar personalizzato. E ambientato in:

-(id)initWithFrame:(CGRect)frame{ 
forceFullHeightInLandscape = YES; 

funzionato come un fascino

+0

È anche possibile sovrascriverlo in una categoria UINavigationBar: '- (BOOL) forceFullHeightInLandscape { return YES; } ' –

2

Simile alla risposta di Joost, ma mettendo il metodo in willAnimateRotationToInterfaceOrientation ha un migliore effetto di animazione di willRotateToInterfaceOrientation. (Non c'è nessun ritardo animazione)

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    [self.navigationBar sizeToFit]; 
} 
-1
(void)viewWillLayoutSubviews { 
     self.navigationItem.titleView.bounds = self.navigationController.navigationBar.bounds; 
}