Cambiar la altura de UITableView dinámicamente

Quiero cambiar el alto de mi tabla vista desde otro controlador de vista basado en la sum de las alturas de sus celdas, ya que son dinámicas. ¿Es posible? Gracias

Añadir:

Lo que básicamente tengo es un UserProfileViewController que tiene una vista contenedor en la mitad de la pantalla. Ahí agrego otros diferentes controladores de visualización:

enter image description here

enter image description here

En el caso del botón de pared, así es como agrego ViewController y su siguiente tabla vista:

- (IBAction)wallButtonPressed:(id)sender { //Check if there is an instance of the viewcontroller we want to display. If not make one and set it's tableview frame to the container's view bounds if(!_userWallViewController) { self.userWallViewController = [[WallViewController alloc] init]; // self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds; } [self.userWallViewController.containerView addSubview:self.userWallViewController.activityFeedTableView]; //If the currentviewcontroller adn it's view are already added to the hierarchy remove them [self.currentViewController.view removeFromSuperview]; [self.currentViewController removeFromParentViewController]; //Add the desired viewcontroller to the currentviewcontroller self.currentViewController = self.userWallViewController; //Pass the data needed for the desired viewcontroller to it's instances self.userWallViewController.searchURLString = [NSString stringWithFormat:@"event/user/%@/", self.userID]; self.userWallViewController.sendCommentURLString = [NSString stringWithFormat:@"event/message/%@", self.userID]; [self.userWallViewController.activityFeedTableView reloadData]; self.userWallViewController.totalCellHeight = ^(float totalCellHeight){ self.scrollView.contentSize = CGSizeMake(320.0, totalCellHeight); CGRect newFrame = self.userWallViewController.containerView.frame; newFrame.size.height = totalCellHeight + 33.0; self.userWallViewController.containerView.frame = newFrame; self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds; }; //Add this containerview to the desired viewcontroller's containerView self.userWallViewController.containerView = self.containerView; //Add the needed viewcontroller and view to the parent viewcontroller and the containerview [self addChildViewController:self.userWallViewController]; [self.containerView addSubview:self.userWallViewController.view]; //CLEAN UP THE CONTAINER VIEW BY REMOVING THE PREVIOUS ADDED TABLE VIEWS [self.userFansViewController.userSimpleTableView removeFromSuperview]; [self.fanOfViewController.userSimpleTableView removeFromSuperview]; [self.userPublishedMovellaListViewController.gridView removeFromSuperview]; [self.userPublishedMovellaListViewController removeFromParentViewController]; self.userPublishedMovellaListViewController = nil; } 

y en ese viewcontroller aquí es donde inicializo mi tabla:

 -(UITableView *)activityFeedTableView { if (!_activityFeedTableView) { _activityFeedTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 850.0) style:UITableViewStylePlain]; } return _activityFeedTableView; } 

Estoy calculando la sum total de la altura de la celda, el problema es que el método de la altura de la celda se llama mucho después de que se recibe el resultado de la vista de tabla. Entonces necesitaría algún tipo de forma de saber cuándo se completa el método de altura de las celdas para todas las celdas y luego puedo cambiar el tamaño de mi tabla. Gracias

No hay una función del sistema para cambiar la altura de la tabla en función del contenido de la tabla vista. Una vez dicho esto, es posible cambiar de forma programática la altura de la tabla vista en función de los contenidos, específicamente en función del tamaño del contentSize de la tabla (lo que es más fácil que calcular manualmente la altura). Algunos de los detalles varían dependiendo de si está usando la nueva función de autodiseño que es parte de iOS 6 o no.

Pero suponiendo que está configurando el modelo subyacente de su vista de tabla en viewDidLoad , si desea ajustar la altura de la vista de tabla, puede hacerlo en viewDidAppear :

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

Del mismo modo, si alguna vez realiza un reloadData (o agrega o elimina filas) para una vista de tabla, querrá asegurarse de que también llame manualmente a adjustHeightOfTableView , por ejemplo:

 - (IBAction)onPressButton:(id)sender { [self buildModel]; [self.tableView reloadData]; [self adjustHeightOfTableview]; } 

Entonces la pregunta es qué debería hacer nuestra adjustHeightOfTableview . Desafortunadamente, esta es una función de si usa el autolayout iOS 6 o no. Puede determinar si tiene habilitada la función de apertura automática abriendo su storyboard o NIB y vaya al “Inspector de archivos” (por ejemplo, presione la opción + comando + 1 o haga clic en la primera pestaña del panel a la derecha):

enter image description here

Supongamos por un segundo que el diseño automático estaba apagado. En ese caso, es bastante simple y adjustHeightOfTableview simplemente ajustaría el frame de la tabla:

 - (void)adjustHeightOfTableview { CGFloat height = self.tableView.contentSize.height; CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y; // if the height of the content is greater than the maxHeight of // total space on the screen, limit the height to the size of the // superview. if (height > maxHeight) height = maxHeight; // now set the frame accordingly [UIView animateWithDuration:0.25 animations:^{ CGRect frame = self.tableView.frame; frame.size.height = height; self.tableView.frame = frame; // if you have other controls that should be resized/moved to accommodate // the resized tableview, do that here, too }]; } 

Sin embargo, si su diseño automático estaba activado, adjustHeightOfTableview ajustaría una restricción de altura para su tabla vista:

 - (void)adjustHeightOfTableview { CGFloat height = self.tableView.contentSize.height; CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y; // if the height of the content is greater than the maxHeight of // total space on the screen, limit the height to the size of the // superview. if (height > maxHeight) height = maxHeight; // now set the height constraint accordingly [UIView animateWithDuration:0.25 animations:^{ self.tableViewHeightConstraint.constant = height; [self.view setNeedsUpdateConstraints]; }]; } 

Para que esta última solución basada en restricciones funcione con Autolayout, primero debemos ocuparnos de algunas cosas:

  1. Asegúrese de que su tabla vista tenga una restricción de altura haciendo clic en el botón central en el grupo de botones aquí y luego elija agregar la restricción de altura:

    agregar restricción de altura

  2. A continuación, agregue un IBOutlet para esa restricción:

    agregar IBOutlet

  3. Asegúrese de ajustar otras restricciones para que no entren en conflicto si ajusta el tamaño de la tabla vista programáticamente. En mi ejemplo, la vista de tabla tenía una restricción de espacio final que la bloqueaba en la parte inferior de la pantalla, así que tuve que ajustar esa restricción para que en lugar de estar bloqueada en un tamaño particular, pudiera ser mayor o igual a un valor, y con una prioridad más baja, para que la altura y la parte superior de la vista de tabla registren el día:

    ajustar otras restricciones

    Lo que hagas aquí con otras limitaciones dependerá por completo de qué otros controles tienes en tu pantalla debajo de la vista de tabla. Como siempre, lidiar con las limitaciones es un poco incómodo, pero definitivamente funciona, aunque los detalles en su situación dependen completamente de qué más tenga en la escena. Pero espero que entiendas la idea. En pocas palabras, con el diseño automático, asegúrese de ajustar sus otras restricciones (si las hay) para que sean flexibles para tener en cuenta la altura cambiante de la tabla.

Como puede ver, es mucho más fácil ajustar programáticamente la altura de una vista de tabla si no está utilizando el autodiseño, pero en caso de que lo esté, presento ambas alternativas.

crea tu celda por xib o guión gráfico. dar su contenido de salida. ahora llámalo en CellForRowAtIndexPath. p.ej. si desea establecer la altura de la celda de acuerdo con el texto de la etiqueta de Comentario. enter image description here

así que establece tus comentariosLbl.numberOfLine = 0; enter image description here

así que establece tus comentariosLbl.numberOfLine = 0;

luego en ViewDidLoad

  self.table.estimatedRowHeight = 44.0 ; self.table.rowHeight = UITableViewAutomaticDimension; 

y ahora

 -(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return UITableViewAutomaticDimension;} 

Muchas de las respuestas aquí no respetan los cambios de la tabla o son demasiado complicadas. Usar una subclase de UITableView que establezca adecuadamente intrinsicContentSize es una solución mucho más fácil cuando se utiliza el diseño automático. No se requieren restricciones de altura, etc.

 class UIDynamicTableView: UITableView { override var intrinsicContentSize: CGSize { self.layoutIfNeeded() return CGSize(width: UIViewNoIntrinsicMetric, height: self.contentSize.height) } override func reloadData() { super.reloadData() self.invalidateIntrinsicContentSize() } } 

Establezca la clase de su TableView en UIDynamicTableView en el constructor de interfaz y observe la magia ya que este TableView cambiará su tamaño después de una llamada a reloadData() .

Esto se puede simplificar enormemente con solo 1 línea de código en viewDidAppear:

  override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) tableViewHeightConstraint.constant = tableView.contentSize.height } 

La solución de Rob es muy buena, solo una cosa que en su -(void)adjustHeightOfTableview método el llamado de

 [self.view needsUpdateConstraints] 

no hace nada, solo devuelve una bandera, en lugar de llamar

 [self.view setNeedsUpdateConstraints] 

hará el efecto deseado.

Usa un código simple y fácil

 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { let myCell = tableView.dequeueReusableCellWithIdentifier("mannaCustumCell") as! CustomCell let heightForCell = myCell.bounds.size.height; return heightForCell; } 

para cambiar el tamaño de mi mesa fui con esta solución en mi controlador de tabla de vista que está perfectamente bien:

 [objectManager getObjectsAtPath:self.searchURLString parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { NSArray* results = [mappingResult array]; self.eventArray = results; NSLog(@"Events number at first: %i", [self.eventArray count]); CGRect newFrame = self.activityFeedTableView.frame; newFrame.size.height = self.cellsHeight + 30.0; self.activityFeedTableView.frame = newFrame; self.cellsHeight = 0.0; } failure:^(RKObjectRequestOperation *operation, NSError *error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; NSLog(@"Hit error: %@", error); }]; 

La parte de cambio de tamaño está en un método, pero aquí está para que pueda verlo. Ahora, el único problema que tengo es cambiar el tamaño de la vista de desplazamiento en el otro controlador de vista, ya que no tengo idea de cuándo ha terminado de cambiar el tamaño de la tabla. Por el momento lo estoy haciendo con performSelector: afterDelay: pero esta no es realmente una buena manera de hacerlo. ¿Algunas ideas?

Encontré que agregar restricciones por progtwigción es mucho más fácil que en el guión gráfico.

  var leadingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.LeadingMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: 0.0) var trailingMargin = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TrailingMargin, relatedBy: NSLayoutRelation.Equal, toItem: mView, attribute: NSLayoutAttribute.TrailingMargin, multiplier: 1, constant: 0.0) var height = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: screenSize.height - 55) var bottom = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.BottomMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1, constant: screenSize.height - 200) var top = NSLayoutConstraint(item: self.tableView, attribute: NSLayoutAttribute.TopMargin, relatedBy: NSLayoutRelation.Equal, toItem: self.mView, attribute: NSLayoutAttribute.TopMargin, multiplier: 1, constant: 250) self.view.addConstraint(leadingMargin) self.view.addConstraint(trailingMargin) self.view.addConstraint(height) self.view.addConstraint(bottom) self.view.addConstraint(top)