2011-12-15 20 views
26

Tengo un UIViewController que contiene un UITableView. Este UIViewController se muestra en un UIPopoverController.Cómo cambiar dinámicamente el tamaño del contenido de UIPopoverController?

Ahora, las cosas es que el número de elementos en el tableView no es constante, y quiero que el tamaño de la popover (es decir - la popoverContentSize), para ajustar de acuerdo con el número de elementos en el tableView

Ingenuamente, estaba pensando que si configuraba el contentSizeForViewInPopover en viewDidLoad después de cargar el tableView con todos los elementos, lo haré.

No lo hizo.

Así que, para resumir, mi pregunta es: ¿Cómo puedo cambiar el popoverContentSize directamente desde el contentViewController - después de haber sido presentado?

Apéndice: enter image description here

Respuesta

46

que podría ser muy tarde para responder, pero para el nuevo usuario de iOS 7 por favor utilice la siguiente línea en su UIViewController i, e contentViewController de su UIPopOverViewConotroller

-(void) viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:animated]; 
    self.preferredContentSize=myTableView.contentSize; 
} 

Esperamos que esto ayuda para el usuario de iOS 7.

+8

esto puede funcionar mejor en ViewWillAppear, como ocurre antes de que aparezca la vista. – nh32rg

+1

si está utilizando navigationController dentro de popover y el problema está ocurriendo incluso después de establecer preferredContentSize. Pruebe [self.parentPopOverController setPopoverContentSize: CGSizeMake (250, 400) animado: SÍ]; antes de presionar UIViewController – Hassy

+1

Se aceptó su respuesta porque está más actualizada. ¡Gracias! –

9

Bueno, al final me hice algo que no estoy seguro si es lo que hay que hacer, pero se está trabajando.

que añade una referencia en mi contentViewController a la popoverController:

@property (nonatomic , assign) UIPopoverController *popoverControllerContainer; 

Entonces, he añadido el código de cambio de tamaño a viewWillAppear y viewDidAppear:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.tableView reloadData]; 
} 

-(void) viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    self.contentSizeForViewInPopover = self.tableView.contentSize; 
} 

-(void) viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    [self.popoverControllerContainer setPopoverContentSize:self.contentSizeForViewInPopover animated:YES]; 
} 

Por lo tanto, mantener una referencia a la popover es tipo de hack-ish, entonces estoy abierto a escuchar mejores ideas.

+0

uso el mismo mecanismo. Estoy agregando el método 'createPopover' a los UIViewControllers que se usan como contenido de popover. Los métodos crean un popover de 'self' y luego guarda la instancia de popover para un mayor acceso. – Sulthan

+0

Hola @Avraham Tu respuesta fue la que utilicé y está funcionando muy bien. Tengo una pregunta sobre su solución: ¿por qué configuró el contenido de la vista en el método will will appear y apareció el tamaño de popover en el? ¿Por qué no se puede hacer en uno de los dos métodos, porque lo intenté y no funcionó? –

+0

Use ambos códigos entre sí y eso funcionará :) –

7

Una clase UIViewController tiene la propiedad

self.contentSizeForViewInPopover 

que se cambie el tamaño del pop sobre w/sin necesidad de siquiera añadiendo una referencia a él.

Y para ampliar una solución, utilicé el método rectForSection: para obtener el tamaño de la sección (la mía solo tiene 1 sección, lo suficientemente fácil de conseguir) y luego agregué la altura de la barra de navegación (parece ser 20). por lo que soy capaz de crear el popover el tamaño de la vista de tabla final:

CGRect sectionRect = [view.tableView rectForSection:0]; 

if (sectionRect.size.height + 20 < POPOVER_SIZE.height) 
    view.contentSizeForViewInPopover = CGSizeMake(POPOVER_SIZE.width, sectionRect.size.height + 20); 
else 
    view.contentSizeForViewInPopover = POPOVER_SIZE; 

podría resultar más difícil con múltiples secciones, i no lo probé. debería ser capaz de resumir las alturas de sección, pero podría haber algunos problemas de espacio que no sé.

+2

Desaprobado, use "preferredContentSize" de iOS7 y posterior. – Satyam

0

Estaba teniendo el mismo problema y ninguna de las respuestas que encontré funcionó. Arreglé juntos que creo que funciona bien.

Tengo una matriz en mi initWithCoder que guarda mis valores. Simplemente ejecuto este código:

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
//Popover Choices 

_importantChoices = [NSMutableArray array]; 
[_importantChoices addObject:@"Bakery"]; 
[_importantChoices addObject:@"Beverage Dry Mix"]; 
[_importantChoices addObject:@"Beverage RTD"]; 
[_importantChoices addObject:@"Crisps"]; 
[_importantChoices addObject:@"Meat"]; 
[_importantChoices addObject:@"Supplements"]; 


//Calculate size of Popover 
self.clearsSelectionOnViewWillAppear = NO; 
NSInteger rowsCount = [_importantChoices count]; 
NSInteger singleRowHeight = [self.tableView.delegate tableView:self.tableView 
             heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
NSInteger totalRowsHeight = rowsCount * singleRowHeight; 
CGFloat largestLabelWidth = 0; 
for (NSString *tmp in _importantChoices) { 
    CGSize labelSize = [tmp sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20.0f]}]; 
    if (labelSize.width > largestLabelWidth) { 
     largestLabelWidth = labelSize.width; 
    } 
} 
CGFloat popoverWidth = largestLabelWidth + 100;  //Add a little padding to the width 
self.preferredContentSize = CGSizeMake(popoverWidth, totalRowsHeight); 
return self; 
} 
7

Para iOS 7 o superior.

- (CGSize)preferredContentSize { 
    return CGSizeMake(320, 550); 
} 

Si es hijo de un contenedor, redirija el tamaño del contenido a usted mismo. P.ej. En una subclase UINavigationController:

- (CGSize)preferredContentSize { 
    return self.topViewController.preferredContentSize; 
} 
+0

Solo una nota para otros que prueban el enfoque de Robert. Está muy limpio y funciona para esta pregunta. Sin embargo, puede no funcionar para usted si presenta un UITableView dentro de un UINavigationController. Avinash parece funcionar en ese caso. – DenVog

+0

@DenVog - Buen lugar. Todavía preferiría subclasificar 'UINavigationController' para obtener su barra de estado preferida de su topViewController. En general, considero que el enfoque de declarar lo que necesita es mejor que establecer un valor, ya que previene errores donde 2 clases diferentes pueden pisotear la misma propiedad con diferentes valores que pueden llevar a resultados diferentes según el orden en que se realicen las cosas. Esto es similar a por qué se creó 'preferredStatusBarStyle' en iOS 7. – Robert

+0

Esta fue la única solución que funcionó para mí. Establecer self.preferredContentSize no tuvo ningún efecto. – pls

0

iOS8 solución/9 - acaba de anular preferredContentSize y forzar la vista de tabla a la disposición antes de la devolución es contentSize.

- (CGSize)preferredContentSize { 
    [self.tableView layoutIfNeeded]; 
    return self.tableView.contentSize; 
} 
+0

esto hace crecer la vista, pero nunca la reduce si está incrustada en una jerarquía 'UINavigationController'. – Mojo66

1

Mi aplicación tiene un menú con submenús procedente de un popover y incrustado en un controlador de navegación, es decir, algo así como UINavigationController ->TopMenuViewController ->SubMenuViewController xN.

Ninguna de las soluciones anteriores funcionó para mí.

Mi solución: En mi menú raíz de clase controlador de vista, de la cual todos los otros controladores de vista menú de heredar, añada el siguiente código:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.navigationController.preferredContentSize = CGSizeMake(450.0f, 0.0f);// increase standard width (320.0) 
} 


- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    self.navigationController.preferredContentSize = self.tableView.contentSize; 
} 
0

Esto debería hacer el truco

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 

    self.preferredContentSize = CGSizeMake(0, self.tableView.contentSize.height)} 
Cuestiones relacionadas