He estado aplastando mi cabeza contra la pared con esto durante las últimas 3 o 4 horas y parece que no puedo entenderlo. Tengo un UIViewController con un UITableView de pantalla completa dentro (hay algunas otras cosas en la pantalla, por lo que no puedo usar un UITableViewController) y quiero que mi tableHeaderView cambie de tamaño con el diseño automático. No hace falta decir que no está cooperando.
Vea la captura de pantalla a continuación.
Debido a que la etiqueta de descripción general (por ejemplo, el texto "Lista de información general aquí") tiene contenido dinámico, estoy usando el diseño automático para cambiar su tamaño y es una supervista. Tengo todo cambiando de tamaño muy bien, excepto por tableHeaderView, que está justo debajo de Paralax Table View en la jerarquía.
La única forma que he encontrado para cambiar el tamaño de esa vista de encabezado es programáticamente, con el siguiente código:
CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = headerFrameHeight;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];
En este caso, headerFrameHeight es un cálculo manual de la altura tableViewHeader de la siguiente manera (innerHeaderView es el área blanca, o la segunda "Vista", headerView es tableHeaderView) :
CGFloat startingY = self.innerHeaderView.frame.origin.y + self.overviewLabel.frame.origin.y;
CGRect overviewSize = [self.overviewLabel.text
boundingRectWithSize:CGSizeMake(290.f, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName: self.overviewLabel.font}
context:nil];
CGFloat overviewHeight = overviewSize.size.height;
CGFloat overviewPadding = ([self.overviewLabel.text length] > 0) ? 10 : 0; // If there's no overviewText, eliminate the padding in the overall height.
CGFloat headerFrameHeight = ceilf(startingY + overviewHeight + overviewPadding + 21.f + 10.f);
El cálculo manual funciona, pero es torpe y propenso a errores si las cosas cambian en el futuro. Lo que quiero poder hacer es que el tableHeaderView cambie de tamaño automáticamente en función de las restricciones proporcionadas, como puede hacerlo en cualquier otro lugar. Pero por mi vida, no puedo entenderlo.
Hay varias publicaciones en SO sobre esto, pero ninguna es clara y terminó confundiéndome más. Aquí hay algunos:
Realmente no tiene sentido cambiar la propiedad translatesAutoresizingMaskIntoConstraints a NO, ya que eso solo me causa errores y no tiene sentido conceptualmente de todos modos.
¡Cualquier ayuda sería realmente apreciada!
EDICIÓN 1: Gracias a la sugerencia de TomSwift, pude resolverlo. En lugar de calcular manualmente la altura de la descripción general, puedo hacer que se calcule para mí de la siguiente manera y luego volver a configurar tableHeaderView como antes.
[self.headerView setNeedsLayout];
[self.headerView layoutIfNeeded];
CGFloat height = [self.innerHeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + self.innerHeaderView.frame.origin.y; // adding the origin because innerHeaderView starts partway down headerView.
CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = height;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];
Edición 2: como han señalado otros, la solución publicada en la Edición 1 no parece funcionar en viewDidLoad. Sin embargo, parece funcionar en viewWillLayoutSubviews. Código de ejemplo a continuación:
// Note 1: The variable names below don't match the variables above - this is intended to be a simplified "final" answer.
// Note 2: _headerView was previously assigned to tableViewHeader (in loadView in my case since I now do everything programatically).
// Note 3: autoLayout code can be setup programatically in updateViewConstraints.
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[_headerWrapper setNeedsLayout];
[_headerWrapper layoutIfNeeded];
CGFloat height = [_headerWrapper systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGRect headerFrame = _headerWrapper.frame;
headerFrame.size.height = height;
_headerWrapper.frame = headerFrame;
_tableView.tableHeaderView = _headerWrapper;
}
setTableHeaderView
no funciona en Xcode6. El problema es que las celdas están superpuestas por tableHeaderView. Sin embargo, funciona en Xcode5