Domanda

Quindi ho questa applicazione per iPhone con una configurazione nidificato in questo modo: [RootViewController] -> [UITabBarController] -> [UINavigationController] -> [subViewControllers]. Tutto è costruito a livello di codice, non in Interface Builder.

Sto semplicemente cercando di sostenere tutti gli orientamenti del dispositivo. Tutte le mie maschere ridimensionamento automatico sono istituiti e ruota tutto e si espande / contratti, se necessario. Tutto tranne che per navBar e barra degli strumenti del navigationController. (Normalmente, questi punti di vista il ridimensionamento automatico automaticamente a seconda dell'orientamento. Cioè Nel paesaggio, la barra di navigazione e la barra degli strumenti dovrebbe ridimensionare automaticamente a circa 32px, e 44px in modalità Portrai.) Che cosa è singolare è che la visualizzazione secondaria del controller di navigazione è il ridimensionamento, ma l'attuale navBar e barra degli strumenti non sono. In altre parole, i tratti contenuti / restringe circa 12 px o così in qualsiasi direzione, come se la barra di navigazione e barra ridimensionato. Questo sembra essere il ridimensionamento automatico delle maschere facendo il loro lavoro.

Quindi, al fine di tentare di risolvere questa situazione, ho creato una categoria per UINavigationController che risponde a 'willRotateToInterfaceOrientation: Durata:' al fine di innescare il selettore 'sizeToFit'. (Questa tecnica è venuto da un altro post su Stack Overflow, con un problema simile.) Ho scoperto, nella mia ricerca, che solo il controller della vista più esterno riceve questo messaggio, tuttavia, così ho il mio controller di vista radice chiamare questo sul regolatore scheda, che a sua volta, chiama sul controller di navigazione, ecc Questo è preso cura di quel problema, e ora i miei controller di vista nested vengono avvisati quando viene ruotata la vista esterna. Utilizzando la tecnica sizeToFit, sia la barra di navigazione e la barra degli strumenti sono il ridimensionamento per conto proprio. Tuttavia, che lascia ancora il problema del riposizionamento della barra degli strumenti, al fine di compensare l'offset dal cambio formato. (Dal nostro punto di vista le coordinate di iPhone iniziare in alto a sinistra).

Ciò che rende questo difficile da fare all'interno del metodo willRotate, è che non abbiamo modo di sapere quali saranno le nuove dimensioni di delimitazione vista, né sappiamo ciò che il nostro orientamento attuale è. (A meno che non si dispone di deviceOrientationNotifications acceso, che non lo faccio.) Tutto quello che dobbiamo lavorare con quello che è il nuovo orientamento sarà, e quali valori attuali del telaio della nostra barra degli strumenti sono. Ho potuto codificare queste e regolazioni telaio Calcola la vecchia maniera con un pezzo di carta zero, ma voglio conservare la visione dinamica dimensionamento caratteristiche senza fare alcuna ipotesi circa le dimensioni dello schermo del dispositivo.

Quindi, utilizzando il seguente codice, sono riuscito a porre rimedio a questo semplicemente 'urtare' la barra degli strumenti 12px in relazione alla dimensione è appena diventato. Al fine di evitare che over-urtante quando l'utente lancia il dispositivo, uso altezza del telaio della barra corrente per ricavare l'orientamento corrente. (Questo significa che ancora sto facendo un presupposto per quanto riguarda la barra degli strumenti di prima e dopo i formati, ma mi sento meglio di che, dal momento che posso influenzare che ad un grado invece di cercare di programmazione di ridimensionamento dello schermo fisico del dispositivo.)

@implementation UINavigationController (BLUINavigationControllerAutoRotate)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return TRUE;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // Resize the navBar
    [[self navigationBar] performSelector:@selector(sizeToFit)
                               withObject:nil
                               afterDelay:(0.5f * duration)];

    // Read our current frame size
    CGRect toolbarFrame = self.toolbar.frame;

    // Prevent over adjusting when flipping the device
    if ((toolbarFrame.size.height < 38
         && (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
             || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
        || (toolbarFrame.size.height > 38
            && (toInterfaceOrientation == UIInterfaceOrientationPortrait
                || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)))
    {
        // We are already resized and repositioned.
        return;
    }

    // Calculate and apply the toolbar offset
    const NSInteger delta = 12;     // the difference in size between 44 and 32 px.
    toolbarFrame.origin.y += ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
                              || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) ? (delta) : (-delta);
    self.toolbar.frame = toolbarFrame;

    // Resize the toolbar
    [[self toolbar] performSelector:@selector(sizeToFit)
                         withObject:nil
                         afterDelay:(0.5f * duration)];

}

@end

Così, ora ho ben comportata NavigationBar e barra degli strumenti. L'utente finale non saprà mai che ho dovuto implementare tutti questo extra-lavoro intorno al fine di riattivare quello che sembra che dovrebbe essere un comportamento standard. Quindi la mia domanda è: perché devo fare tutto questo? C'è un approccio migliore che dovrei sapere, o qualcosa che semplicemente non sto facendo altrove? (Vale a dire [navigationController setAutomaticallyResizesToolbarOnRotate: TRUE];? O qualcosa di simile) Come ho detto, questo sembra come dovrebbe essere pre-cablati, quindi per me avere a finagle con messaggi di inoltro e trigger forzate si sente come un mod sovra-ingegnerizzato piuttosto che la soluzione adeguata.

Grazie!

È stato utile?

Soluzione

si sta passando il messaggio willRotateToInterfaceOrientation al controller della vista scheda dal controller della vista root - perché non trasferire tutti gli altri messaggi di rotazione e vedere se funziona? cioè.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation  {
    [super didRotateFromInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didRotateFromInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    [super didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
}

Sarei curioso di vedere che cosa succede se si passa tutti questi al controller barra delle schede - il problema sembra come qualcosa che dovrebbe accadere automaticamente, invece di essere tutto il lavoro extra che hai fatto

!
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top