2010-03-12 9 views
10

Quiero diseñar un controlador de vista/vista que automáticamente muestra/oculta una subvista cuando está en orientación horizontal. Quiero que la subvista desaparezca por completo y otras subvistas ocupen su espacio.¿Cómo ocultar un UIView por completo al cambiar de orientación?

El uso de un UIViewController, escribí código que establece la propiedad marco de las subvistas y lo llaman en:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration; 

Esto resuelve el problema de la mayoría de las veces, pero tiene problemas cuando el cambio de orientación que está sucediendo cuando la vista no está apareciendo de pasar por alto esto, yo también estoy llamando el método de cambio de tamaño en:

- (void)viewWillAppear:(BOOL)animated; 

pero esto no tiene problemas en algunos casos poco frecuentes (que implican un UISearchDisplayController), así que también estoy llamando el método de cambio de tamaño en

- (void)viewDidAppear:(BOOL)animated; 

Como puede comprender, no estoy satisfecho con este código y estoy buscando una forma mejor/más eficaz de hacerlo.

¿Alguna idea?

+0

Ofrezco una recompensa por esta pregunta. En mi caso, tengo un UIWebView en el centro de mi vista, con un anuncio publicitario en la parte inferior. Quiero eliminar el banner publicitario y cambiar el tamaño de UIWebView para llenar el espacio faltante al cambiar el tamaño. Intenté simplemente eliminar el banner de la supervista, pero el UIWebView no cambia de tamaño para llenar el espacio vacío (aunque todas las máscaras de aumento automático están habilitadas). –

Respuesta

0

Dentro

- (void)didRotateFromInterfaceOrientation: 
    (UIInterfaceOrientation)fromInterfaceOrientation 

Para ocultarlo

sub_view.hidden = YES; 

Para mostrar de nuevo

sub_view.hidden = NO; 
+1

gracias por su respuesta, pero la propiedad oculta solo oculta la vista. No cambia el tamaño de otras vistas para ocupar su espacio. –

+0

Oh, quieres hacer eso. ¿Ha comprobado si puede usar layoutSubviews y layout IfNeeded? –

0

Si hay varios subvistas que necesitan ser presentado de manera muy diferente en el paisaje y el retrato , entonces puede ser más fácil hackearlo con un UIView adicional, por ejemplo, landscapeView, agregado en el IB. Cargue esta vista con botones, subvistas, etc. y colóquela como desee. Puede usar todas las mismas conexiones que con la vista usual (retrato). Recuerde declarar IBOutlet UIView *landscapeView; en el encabezado. A continuación, puede añadir la vista utilizando la siguiente:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation 
           duration:(NSTimeInterval)duration 
{ 
    if ([landscapeView superview]) { 
     if (toOrientation == UIInterfaceOrientationPortrait || 
      toOrientation == UIInterfaceOrientationPortraitUpsideDown) { 
      [landscapeView removeFromSuperview]; 
     } 
    } else { 
     if (toOrientation == UIInterfaceOrientationLandscapeLeft || 
      toOrientation == UIInterfaceOrientationLandscapeRight) { 
      [[self view] addSubview:landscapeView]; 
     }  
    } 
} 

Si el tiempo no funciona como te gusta, entonces usted podría también intentar algo similar en el interior

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;

Si desea obtener incluso más elegante, entonces puede dejar vacía la vista principal, crear un UIView *portraitView y un UIView *landscapeView, luego eliminar la vista actual en willRotateToInterfaceOrientation y agregar la nueva vista en didRotateToInterfaceOrientation.

Para estar seguro, también debe asegurarse de que la visión correcta se muestra inicialmente:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    UIInterfaceOrientation toOrientation = self.interfaceOrientation; 
    if (toOrientation == UIInterfaceOrientationPortrait || 
     toOrientation == UIInterfaceOrientationPortraitUpsideDown) { 
     [self.view addSubview:portraitView]; 
    } else { 
     [self.view addSubview:landscapeView]; 
    } 

} 

y también

- (void)viewWillDisappear:(BOOL)animated 
{ 
    if ([landscapeView superview]) { 
     [landscapeView removeFromSuperview]; 
    } 
    if ([portraitView superview]) { 
     [portraitView removeFromSuperview]; 
    } 
} 
+0

Ninguna de estas opciones funcionará en mi caso [y yo soy el que actualmente ofrece una recompensa :-)]. Tengo un UIWebView con un banner publicitario en la parte inferior; Quiero quitar el banner en la vista de paisaje. Si intento la solución n. ° 1 para eliminar el banner, UIWebView no cambia de tamaño para ocupar el espacio. Si intento la solución n. ° 2, no puedo compartir el UIWebView entre las vistas de paisaje/retrato separadas. –

+0

Oh. Si eso es todo lo que necesita, simplemente cambie manualmente el tamaño de la vista web. – PengOne

0

una opción es presentar una visión modal con una transición de fundido en rotación y descartarlo cuando se gira hacia atrás.

10

Suponiendo que todo lo que tienes es un UIWebView y un anuncio de la bandera, a continuación, puedes cambiar el tamaño manualmente la web View en orientación horizontal:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation 
           duration:(NSTimeInterval)duration 
{ 
    if (toOrientation == UIInterfaceOrientationPortrait || 
     toOrientation == UIInterfaceOrientationPortraitUpsideDown) { 
      [adView setHidden:NO]; 
     } 
    } else { 
     if (toOrientation == UIInterfaceOrientationLandscapeLeft || 
      toOrientation == UIInterfaceOrientationLandscapeRight) { 
      [adView setHidden:YES]; 
     }  
    } 
} 

Entonces también hacen

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation 
           duration:(NSTimeInterval)duration 
{ 
    UIInterfaceOrientation toOrientation = self.interfaceOrientation; 
    if (toOrientation == UIInterfaceOrientationPortrait || 
     toOrientation == UIInterfaceOrientationPortraitUpsideDown) { 
      [webView setBounds:CGRectMake(0.0,0.0,320.0,436.0)]; 
     } 
    } else { 
     if (toOrientation == UIInterfaceOrientationLandscapeLeft || 
      toOrientation == UIInterfaceOrientationLandscapeRight) { 
      [webView setBounds:CGRectMake(0.0,0.0,480.0,320.0)]; 
     }  
    } 
} 

Las dimensiones suponen 44,0 Altura para el banner publicitario y sin barra de navegación (44.0) o barra de estado (20.0), por lo que puede necesitar ajustar los números para su diseño.

+0

Sorprendentemente, esto no funciona, o, mejor dicho, funciona, pero hay una gran trampa. Si cambia el tamaño de esta manera en "willRotate", iOS volverá a transformar los tamaños después de la rotación. Por lo tanto, al ir a retrato, debe cambiar el tamaño de la vista web (actualmente horizontal) a 480x ~ 291 (100% x90%); iOS lo transformará en 320x436. Al ir al paisaje, debe cambiar el tamaño a 320x480, que iOS se transformará en 480x320. (la cabeza explota) ¿Realmente no hay una mejor manera? –

+1

Descompuse mi respuesta anterior en métodos de voluntad y de hecho. Esto debería mejorar la implementación. – PengOne

+0

Hacer el cambio de tamaño en 'didRotateFromInterfaceOrientation' era el truco perdido. También tengo que llamar a este código en 'viewWillAppear', por lo que podría no responder @Panagiotis Korros, pero vale la pena mi recompensa. –

0

Personnaly, para situaciones como esta, me siento como la codificación de la posición de su subView es mucho más simple que depender de la gestión del diseño del marco.

Así, suponiendo que la aplicación muestra una barra de título, que tiene una altura de 20 puntos, esto es lo que yo haría:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 
    CGFloat titleBarHeight = 20; 
    CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height; 
    if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){ 
     webView.frame = CGRectMake(0, 0, 320, 480 - titleBarHeight - navBarHeight - adView.frame.size.height); 
     adView.hidden = NO; 
    }else{ 
     webView.frame = CGRectMake(0, 0, 480, 320 - titleBarHeight - navBarHeight); 
     adView.hidden = YES; 
    } 
} 
+0

Ver mi comentario a @PengOne. Esto es sorprendentemente complicado/poco elegante. ¿Realmente no hay una mejor manera? –

0

que se aprovechan de los límites de la vista padre en mi código. Pruebe el siguiente código para ver si la animación funciona bien para usted.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 
    switch (toInterfaceOrientation) { 
     case UIInterfaceOrientationLandscapeLeft: 
     case UIInterfaceOrientationLandscapeRight: 
     { 
      webView.frame = self.view.bounds; 
     adView.hidden=YES; 
      break; 
     } 
    } 
} 


- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{ 
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 

    switch (fromInterfaceOrientation) { 
     case UIInterfaceOrientationLandscapeLeft: 
     case UIInterfaceOrientationLandscapeRight: 
     { 
      webView.frame = originalFrame; 
      adView.hidden=NO; 
      break; 
     } 
    } 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    adView.autoresizingMask = UIViewAutoresizingFlexibleWidth; 
    originalFrame = webView.frame; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return YES; 
} 
Cuestiones relacionadas