Pregunta

Así que tengo esta aplicación iPhone con una configuración anidada como esto: [RootViewController] -> [UITabBarController] -> [UINavigationController] -> [subViewControllers]. Todo está construido mediante programación, no en el Interface Builder.

Estoy simplemente tratando de apoyar a todas las orientaciones del dispositivo. Todos mis máscaras de tamaño automático están configurados y todo lo que gira y se expande / contratos según sea necesario. Todo a excepción de navBar y barra de herramientas de la NavigationController. (Normalmente, estos puntos de vista cambiar automáticamente el tamaño automáticamente en función de la orientación. Es decir, en el paisaje, la barra de navegación y la barra de herramientas debe cambiar automáticamente el tamaño de alrededor de 32px y 44px en modo Portrai.) ¿Cuál es curioso es que la subvista del mando de navegación se cambio de tamaño, pero la barra de navegación actual y la barra de herramientas no lo son. En otras palabras, los tramos de contenido / contrae alrededor de 12 píxeles o menos en cualquier dirección, como si la barra de navegación y la barra de herramientas redimensionada. Este parece ser el tamaño automáticamente las máscaras haciendo su trabajo.

Así que con el fin de tratar de resolver esta situación, he creado una categoría para UINavigationController que responde a 'willRotateToInterfaceOrientation: duración:' Para que se active el selector 'sizeToFit'. (Esta técnica vino de otro mensaje el desbordamiento de la pila, con un problema similar.) Descubrí, en mi investigación, que sólo el controlador de vista más externa recibe este mensaje, sin embargo, por lo que tengo a mi controlador de vista raíz llamar a esto en el controlador ficha, la cual a su vez lo llama en el controlador de navegación, etc. Esto se hizo cargo de ese problema, y ??ahora mis controladores de vista anidados están siendo notificados cuando se gira la vista exterior. Utilizando la técnica sizeToFit, tanto en la barra de navegación y la barra de herramientas a cambiar el tamaño por sí solos. Sin embargo, eso todavía deja el tema de reposicionamiento de la barra de herramientas, con el fin de compensar el desplazamiento desde el cambio de tamaño. (Desde nuestro punto de vista coordenadas en iPhone comenzar en la parte superior izquierda.)

Lo que hace esto difícil de hacer en el método willRotate, es que no tenemos forma de saber cuál será la nueva vista de delimitación dimensiones, ni sabemos lo que nuestra orientación actual es. (A menos que tenga deviceOrientationNotifications encendido, que no es así.) Todo lo que tenemos que trabajar es lo que será la nueva orientación, y qué valores actuales del marco de nuestra barra de herramientas son. Pude difícil que el código este marco y ajustes calcular la antigua usanza con un trozo de papel cero, pero realmente quiero conservar la visión dinámica dimensionamiento características sin hacer ninguna suposición sobre las dimensiones de la pantalla del dispositivo.

Por lo tanto, usando el siguiente código, he conseguido remediar esto simplemente las sacudidas de la barra de herramientas por 12 píxeles en relación con el tamaño que sólo se convirtió. Con el fin de evitar que se sobre-chocar cuando el usuario voltea el dispositivo, utilizo altura del marco de la barra de herramientas de corriente para derivar la orientación actual. (Esto significa que todavía estoy haciendo una hipótesis respecto a la barra de herramientas de antes y después de tamaños, pero me siento mejor que desde que puedo influir en que en un grado en lugar de tratar de programación cambiar el tamaño físico de la pantalla 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

Así que, ahora que me he comportado adecuadamente navigationbar y barra de herramientas. El usuario final nunca sabrá que tenía que poner en práctica toda esta solución alternativa adicional con el fin de volver a habilitar lo que parece se supone que es un comportamiento estándar. Así que mi pregunta es, ¿por qué tengo que hacer todo esto? ¿Hay un mejor enfoque que debo saber sobre, o algo que simplemente no estoy haciendo en otros lugares? (Es decir, [navigationController setAutomaticallyResizesToolbarOnRotate: TRUE];? O algo por el estilo) Como dije, esto parece que se supone que es pre-cableado, así que para mí tener que finagle con mensajes de tránsito y disparadores se siente forzado como un truco de ingeniería exceso de lugar de la solución apropiada.

Gracias!

¿Fue útil?

Solución

Usted está transmitiendo el mensaje willRotateToInterfaceOrientation al controlador de vista de la ficha de su controlador de vista raíz - ¿por qué no pasa en todos los otros mensajes de rotación y ver si eso ayuda? es decir.

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

Yo estaría interesado en ver lo que sucede si se pasa todo esto a su controlador barra de pestañas - su problema parece como algo que debería ocurrir de forma automática, en lugar de estar todo el trabajo extra que has hecho

!
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top