7

Ho un'app per iPad in cui vorrei nascondere e mostrare un elenco di categorie (un po 'come la piccola vista in un controller di visualizzazione divisa) e la vista principale che contiene uno stack UiNavigationController.UINavigationController: Title Jumps in Resize Animation

Vorrei ridimensionare la vista di UINavigationController per riempire l'intero schermo quando l'elenco delle categorie è nascosto e ridurlo quando mostro l'elenco.

L'ho funzionato, tranne che il titolo della barra di navigazione salta immediatamente al suo nuovo offset quando si imposta il frame all'interno di un blocco di inizio/commit dell'animazione.

Qualche idea su come fermare il salto del titolo?

risposta

3

Ho usato questo per fissare quei salti in UINavigationBar per titolo e tasto destro.

#import "UINavigationBar+My.h" 

@implementation UINavigationBar (My) 

- (void)layoutSubviews { 
for (id obj in [self subviews]) { 
    if ([NSStringFromClass([obj class]) isEqualToString:@"UINavigationItemView"]) 
     [(UIView *)obj setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin]; 
    else if ([NSStringFromClass([obj class]) isEqualToString:@"UIButton"]) { 
     if ([(UIButton *)obj center].x < ([self center].x/2)) 
      [(UIButton *)obj setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin]; 
     else 
      [(UIButton *)obj setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; 
    } 
} 

@end 

spero che vi aiuterà a ;-)

+0

Ciao, grazie per la tua risposta +1. Mi hai sicuramente indirizzato nella giusta direzione, ma non posso accettare la tua risposta così com'è perché è orribile! Nessun controllo di classe ... funzionerà solo se hai solo un titolo e un pulsante RHS (cioè non far fronte al pulsante Indietro). Se l'ordine di visualizzazione delle modifiche alla mela si interromperà, ecc. Si prega di inviare una soluzione più robusta per la risposta da accettare (o risponderò con la mia soluzione)! Saluti :) –

+0

Haha, certo che era orribile! :) Era solo una soluzione rapida nel mio progetto. È meglio questo? Su cosa si basa la tua soluzione? – Adam

+0

Sì, va meglio, accettato! posterò anche il mio ... il tuo non risponderà con il pulsante indietro, e qualche altro possibile scenario, penso. –

2

Mi sono imbattuto in un problema simile di recente; Avevo una sottoview della vista animata che saltava immediatamente alla sua nuova posizione. Questo stava accadendo perché -layoutSubviews veniva chiamato su quella vista come risultato di me che lo modificava programmaticamente prima che l'animazione finisse. Stai facendo qualcosa come cambiare il testo del titolo o modificarlo in un modo che potrebbe causare la chiamata di -layoutSubviews?

+1

Ho avuto una situazione in cui un pezzo di codice chiamato 'layoutIfNeeded' all'interno di' viewWillAppear'. La rimozione di 'layoutIfNeeded' ha rimosso la strana animazione. – greg

1

La mia soluzione, sembra di far fronte a tutti gli scenari mi ha colpito nella mia app. Ovviamente ancora un po 'un hack, quindi non garantisce che funzionerà sempre!

@implementation UINavigationBar (Nick) 

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
     UIView* titleView = nil; 
     CGFloat buttonWidths = 0; 
     for (UIView* subview in [self subviews]) { 

      if ([subview class] == NSClassFromString(@"UINavigationItemView")) { 
       if (titleView) { 
        // Exit here - if there is more than one title, probably doing a pop 
        return; 
       } 
       titleView = subview; 
      } 
      else if ([subview class] == [UIView class] ||       // bar button with custom view 
        [subview class] == NSClassFromString(@"UINavigationButton")) { // or ordinary bar button 

       buttonWidths += subview.frame.size.width; 
       // is it RHS? 
       if (subview.frame.origin.x > subview.frame.size.width) { 
        [subview setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; 
       } 
       else { 
        [subview setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin]; 
       } 
      } 
      else if ([subview class] == NSClassFromString(@"UINavigationItemButtonView")) { 
       // pretty sure this is always the back button 
       buttonWidths += subview.frame.size.width; 
       [subview setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin]; 
      } 
     } 


     if (titleView) { 
      buttonWidths += 20; // seems to be apple indentation 
      CGRect rect = titleView.frame; 
      if (rect.size.width > self.frame.size.width - buttonWidths) { 
       rect.size.width = self.frame.size.width - buttonWidths; 
       titleView.frame = rect; 
      } 

      titleView.center = self.center; 
     } 
    } 
} 
1

Ha funzionato bene per me quando ho incluso [self.navigationController.navigationBar layoutSubviews] nel blocco di animazione stesso. Ecco l'esempio di codice:

[UIView animateWithDuration:0.5 
       animations:^{ 
        [self.navigationController.navigationBar setFrame:newFrame]; 
        [self.navigationController.navigationBar layoutSubviews]; 
       }]; 

Spero che questo sia in qualche modo utile.

+0

non è permesso chiamare '' 'layoutSubviews'''direttamente – CarlJ