UIPopoverController redimensionando automáticamente a la altura máxima en pushViewController


Tengo una ventana emergente que contiene un controlador UINavigationController. Puedo mostrar el popover fine, y contiene el NavController muy bien. El NavController contiene una vista de tabla y cuando selecciono un elemento crea una nueva vista de detalle:

     DeviceDetailViewController *detailViewController = 
[[[DeviceDetailViewController alloc] initWithNibName:@"DeviceDetailViewController" bundle:nil] autorelease];

Luego lo presiono el nuevo controlador de vista:

    [self.navigationController pushViewController:detailViewController animated:YES];

Esto es cuando ocurre el problema: después de empujar la nueva vista, la ventana emergente cambia de tamaño a la altura máxima disponible en el iPad.

He intentado establecer la altura de todas las vistas en el xib a altura fija en lugar de flexible. He intentado establecer explícitamente la altura del popover. También he intentado usar diferentes controladores de vista como la vista hija. El problema sigue siendo: la ventana emergente quiere que cambie su tamaño a la altura máxima automáticamente cada vez que se envía una nueva vista al controlador de navegación.

Aquí hay una pregunta que trata de tratar de controlar deliberadamente el tamaño de la ventana emergente al empujar nuevo vistas:

Pensé que esto podría ser un método de fuerza bruta para controlar el tamaño. Curiosamente, sin embargo, en realidad causa algunas peculiaridades gráficas rápidas (como si la vista estuviera siendo animada recientemente) seguidas de continuar redimensionando como se describió anteriormente.

En otras palabras, algo está forzando literalmente el popover a su altura máxima, y parece ocurrir después de todos los métodos delegados han sido llamados.

Es el controlador de navegación? ¿Alguien ha visto esto? ¿algo así?

Author: Community, 2010-08-11

13 answers

Esto lo arregló para mí después de que tuve el mismo problema (coincidentemente también hoy):

EDITAR : Como contentSizeForViewInPopover está en desuso en iOS7.0, use preferredContentSize.

Respuesta original abajo :

En su detailViewController añadir esto:

- (void)viewWillAppear:(BOOL)animated {

    CGSize size = CGSizeMake(320, 480); // size of view in popover
    self.contentSizeForViewInPopover = size;

    [super viewWillAppear:animated];

}

También desea agregar algo similar a su DeviceDetailViewController original para evitar el cambio de tamaño al tocar el elemento de navegación posterior.

 123
Author: borked,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-03 04:16:41

Al igual que manejarlo en viewWillAppear, otra forma de lidiar con esto es anular contentSizeForViewInPopover. Muy conciso:

-(CGSize)contentSizeForViewInPopover
{
    return self.view.bounds.size;
}
 30
Author: Peter DeWeese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-04 15:54:06

Para IOS5

Te recomiendo que lo hagas en:

- (void)viewDidLoad {
    [super viewDidLoad];

    CGSize size = CGSizeMake(320, 480); // size of view in popover
    self.contentSizeForViewInPopover = size;

}
 30
Author: MUH Mobile Inc.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-14 20:35:24

Tuve un problema similar.

Tuve un popover presente desde un botón en una barra de herramientas. El popover se estableció en un tamaño específico. Era una vista de mesa. Cuando se seleccionó la fila de la tabla, se llamó a un nuevo controlador de vista con un controlador de navegación.

Cuando se seleccionó el botón atrás, la ventana emergente se convirtió en el tamaño predeterminado (creo que 320x1100), en lugar del tamaño específico que deseaba.

El código original era:

  MyTableViewController *myVC = [[MyTableViewController alloc] init];
  UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC];

  UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
  popover.delegate = self;

  popover.popoverContentSize = CGSizeMake(400.0, 500.0);

  [myVC release];
  [navController release];
  [popover release];

He añadido una línea para resolver el problema. Concedido es una especie de trabajo alrededor porque tuve que restar la altura de la cabecera. Tal vez uno de ustedes podría iluminarme con un método mejor. De todos modos, funciona.

  MyTableViewController *myVC = [[MyTableViewController alloc] init];

  UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC];

  UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
  popover.delegate = self;

  popover.popoverContentSize = CGSizeMake(400.0, 500.0);

  //Subtract the height of the header to match the total popover size (not just the view).
  myVC.contentSizeForViewInPopover = CGSizeMake(400.0, 500-44);

  [myVC release];
  [navController release];
  [popover release];

Creo que cuando un controlador nav está involucrado, y se presiona el botón atrás, hace que la ventana emergente tenga su tamaño predeterminado. Al agregar la propiedad contentSizeForViewInPopover para el controlador de vista myVC, fuerza el tamaño específico.

Espero que esto sea útil.

Kurt

 11
Author: Kurt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-09 04:19:19

Para iOS 7 use lo siguiente:

- (void)viewDidLoad
{
    [super viewDidLoad];

    CGSize size = CGSizeMake(320, 768); // size of view in popover
    self.preferredContentSize = size;
}

UIViewController.contentSizeForViewInPopover ha sido obsoleto primero en iOS 7.

 9
Author: Abdullah Umer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-12 15:39:14

En respuesta a fallos gráficos con animaciones:

Las animaciones de UIPopoverController entran en conflicto con las animaciones de los controladores de UINavigation, si crea el popover con un UINavigationController dentro de él. Da lugar a fallos gráficos al animar. Para solucionar el problema, establezca el parámetro animado en false al presionar otros controladores o al mostrar la barra de herramientas.

Empujando Controladores de vista:

[self.navigationController pushViewController:detailViewController animated:NO];

Haciendo visible la barra de herramientas:

[[self navigationController] setToolbarHidden:NO animated:NO]; 

Configuración el animated: NO hará que las animaciones se vean correctamente en un controlador UIPopoverController.

 6
Author: Paul Solt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-19 17:50:00

¿Por qué no simplemente establecer el contentSizeForViewInPopover antes de empujar el siguiente controlador en la pila de navegación? No es necesario establecer tamaños en viewWillAppear y tal.

[nextController setContentSizeForViewInPopover:[self contentSizeForViewInPopover]];
[[self navigationController] pushViewController:nextController animated:YES];

Funciona en IOS 5.1

 5
Author: MrJre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-14 10:33:26

Leve variación en el consejo de borked (que me señaló en la dirección correcta, gracias por eso!), esto es lo que hago al empujar un nuevo controlador para mantener el tamaño antes de empujarlo:

productViewController.contentSizeForViewInPopover = self.view.bounds.size;
self.contentSizeForViewInPopover = self.view.bounds.size;

[self.navigationController pushViewController:productViewController animated:YES];

Me gusta esto porque no tengo que codificar los valores popover en cada controlador de vista (bueno, ya que los uso a varias alturas).

La línea self.contentSizeForViewInPopover es para preservar el tamaño cuando el usuario golpea hacia atrás. Supongo que podrías poner esta línea en otro lugar, como viewWillAppear o donde sea te gusta.

Parece funcionar...

 4
Author: William Denniss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-12 07:25:50

En el - (void)viewDidLoad de todos los controladores de vista que está utilizando en la navegación escriba el código:

self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
 2
Author: SumiSadiq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-03 06:22:38

Hay dos formas de establecer el contentSizeForViewInPopover en el guion gráfico. Puede configurar los controladores de vista que están con su controlador de navegación, para que sean de forma libre y establecer las vistas raíz al tamaño deseado. O bien, puede mantener la métrica simulada como inferida y marcar "Usar tamaño explícito" y establecer el tamaño que desee allí.

Luego, en cada controlador de vista que esté dentro de su controlador de navegación, agregue lo siguiente...

- (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];

     ["yourpopoverController" setPopoverContentSize:CGSizeMake(self.
           contentSizeForViewInPopover.width, seld.contentSizeForViewInPopover.height + self.
           navigationController.navigationBar.frame.size.height) animated:YES];
}

En la animación de transición, la nueva vista vendrá alineado con la parte superior, y luego la altura se ajustará en consecuencia.

De esta manera, no tiene que sobrescribir contentSizeForViewInPopover, o especificar algún otro tamaño específicamente en sus controladores de vista. Todo está en el guion gráfico.

Si uno de sus controladores de vista tiene una altura variable, entonces necesita anular contentSizeForViewInPopover en esa vista de esta manera...

- (CGSize)contentSizeForViewInPopover {
    return CGSizeMake(450, "calculate your height here");
}
 2
Author: Matt Becker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-15 14:45:00

Esto puede haber funcionado una vez, pero no con xCode 6, donde contentSizeForViewInPopover está obsoleto. Afortunadamente, se respeta en el tiempo de carga del guion gráfico. Descargué un editor xml (Xmplify) y hackeé el guion gráfico. Establezca la clave contentSizeForViewInPopover en el tamaño que desee. Guardar y reemplazar (hacer una copia primero) storyboard.

Más específicamente :

< viewController>

     <value key="contentSizeForViewInPopover" type="size" width="450" height="280" / >

</viewController>
 1
Author: Joe313,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-16 17:29:58

No trabajes para mí, cuando uso esto:

[UIPopoverController 
    [UINavigationController] = root vc = [UIViewController vc1] => [UIViewController vc2] 
]

Cuando aparezca popover es todo bueno, presione el botón en vc1 y presione vc2 al controlador de navegación

Luego vuelve a vc1 (raíz) presionando el botón en vc2 (método popToRootViewController);

Podemos ver que el popover cambia de tamaño propio, pero el tamaño vc1 es antiguo... ¿QUÉ ES ESO???

Ok, ahora trabaja... Agregar propiedad popover en mi controlador

self.contentSizeForViewInPopover = (CGSize){400, 200};
self.navigationController.contentSizeForViewInPopover = self.contentSizeForViewInPopover;
self.popover.popoverContentSize = self.contentSizeForViewInPopover;
 0
Author: iTux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-01 09:10:44

Ejecutar Swift 4 e iOS 11 la única solución posible era para mí. Para usar showViewController:sender: and showDetailViewController:sender: en lugar de presentViewController:animated:completion:.

Del Documento de Apple

Los métodos showViewController:sender: y showDetailViewController:sender: ofrecen la forma más adaptable y flexible de mostrar controladores de vista. Estos métodos permiten al controlador de vista de presentación decidir la mejor manera de manejar la presentación. Por ejemplo, un controlador de vista de contenedor puede incorporar el controlador de vista como hijo en lugar de presentándolo modalmente. El comportamiento predeterminado presenta el controlador de vista modalmente.

 0
Author: BilalReffas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-14 13:15:03