2011-01-21 14 views
7

Tengo una aplicación ipad donde me gustaría ocultar y mostrar una lista de categorías (algo así como la vista pequeña en un controlador de vista dividida) y la vista principal que contiene una pila UiNavigationController.UINavigationController: Title Jumps en Resize Animation

Me gustaría cambiar el tamaño de la vista UINavigationController para llenar toda la pantalla cuando la lista de categorías está oculta, y reducir cuando muestro la lista.

Lo tengo funcionando, excepto que el título de la barra de navegación salta inmediatamente a su nuevo desplazamiento al establecer el marco dentro de un bloque de inicio/confirmación de animación.

¿Alguna idea de cómo detener el salto del título?

Respuesta

3

Lo usé para fijar esos saltos en UINavigationBar para el título y el botón derecho.

#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 

espero que le ayudará a ;-)

+0

Hola, gracias por tu respuesta +1. Ciertamente me has señalado en la dirección correcta, pero no puedo aceptar tu respuesta como es porque es horrible. Ninguna comprobación de clase ... solo funcionará si solo tiene un título y un botón RHS (es decir, no soportará el botón Atrás). Si apple cambia el orden de visualización, se romperá ... etc. ¡Por favor envíe una solución más robusta para que la respuesta sea aceptada (o responderé con mi propia solución)! Saludos :) –

+0

Jaja, seguro que era horrible! :) Fue solo una solución rápida en mi proyecto. ¿Es esto mejor? ¿En qué se basa su solución? – Adam

+0

Sí, eso es mejor, ¡aceptado! publicaré la mía también ... la tuya no soportará el botón Atrás, y alguna otra es posible, creo. –

2

Me encontré con un problema similar recientemente; Tenía una subvista de la vista de animación que saltaba de inmediato a su nueva posición. Esto estaba sucediendo porque se llamaba a -layoutSubviews en esa vista como resultado de modificarla programáticamente antes de que terminara la animación. ¿Estás haciendo algo así como cambiar el texto del título o modificarlo de alguna manera que podría llamar al -layoutSubviews?

+1

Tuve una situación en la que un fragmento de código llamado 'layoutIfNeeded' dentro de' viewWillAppear'. Al eliminar el 'layoutIfNeeded' se eliminó la extraña animación. – greg

1

Mi solución, parece que hacer frente a todos los escenarios de golpeo en mi aplicación. Obviamente todavía es un hack, así que no hay garantías de que siempre funcione.

@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

funcionó bien para mí cuando he incluido [self.navigationController.navigationBar layoutSubviews] en el propio bloque de animación. Aquí está el ejemplo de código:

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

espero que esto es de alguna manera útil.

+0

no está permitido llamar '' 'layoutSubviews'''directly – CarlJ