iphone - ejemplo - uitableview tutorial
Cómo cambiar el tamaño de un tableHeaderView de UITableView? (16)
Tengo problemas para redimensionar tableHeaderView. Simplemente no funciona.
1) Crear un UITableView y UIView (100 x 320 px);
2) Establezca UIView como tableHeaderView de UITableView;
3) Build and Go. Todo está bien.
Ahora, quiero redimensionar tableHeaderView, así que agrego este código en viewDidLoad:
self.tableView.autoresizesSubviews = YES;
self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;
CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;
La altura de tableHeaderView debería aparecer con 200, pero aparece con 100.
Si escribo:
self.tableView.autoresizesSubviews = YES;
CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;
self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;
Entonces comienza con 200 de altura, como yo quiero. Pero quiero poder modificarlo en tiempo de ejecución.
También intenté esto, sin éxito:
self.tableView.autoresizesSubviews = YES;
self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;
CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;
[self.tableView.tableHeaderView setNeedsLayout];
[self.tableView.tableHeaderView setNeedsDisplay];
[self.tableView setNeedsLayout];
[self.tableView setNeedsDisplay];
El punto aquí es: ¿cómo cambiamos el tamaño de un tableHeaderView en tiempo de ejecución?
¿Alguien ha podido hacer esto?
Gracias
yo me
Cabecera de redimensionamiento UITableView - UISearchBar con Scope Bar
Quería una UITableView
con UISearchBar
como cabecera de la tabla, así que tengo una jerarquía que se parece a esto
UITableView
|
|--> UIView
| |--> UISearchBar
|
|--> UITableViewCells
UISearchBarDelegate métodos
Como se ha dicho en otra parte, si no configuraTableViewHeader después de cambiarlo, no pasará nada.
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = YES;
[UIView animateWithDuration:0.2f animations:^{
[searchBar sizeToFit];
CGFloat height = CGRectGetHeight(searchBar.frame);
CGRect frame = self.tableView.tableHeaderView.frame;
frame.size.height = height;
self.tableHeaderView.frame = frame;
self.tableView.tableHeaderView = self.tableHeaderView;
}];
[searchBar setShowsCancelButton:YES animated:YES];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = NO;
[UIView animateWithDuration:0.f animations:^{
[searchBar sizeToFit];
CGFloat height = CGRectGetHeight(searchBar.frame);
CGRect frame = self.tableView.tableHeaderView.frame;
frame.size.height = height;
self.tableHeaderView.frame = frame;
self.tableView.tableHeaderView = self.tableHeaderView;
}];
[searchBar setShowsCancelButton:NO animated:YES];
return YES;
}
¿ [self.tableView reloadData]
después de cambiar la altura?
Creo que debería funcionar si solo configuras la altura de myHeaderView así:
CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;
self.tableView.tableHeaderView = myHeaderView;
En iOS 9 y tableHeaderView
posteriores, tableHeaderView
no se rediseñaría después de redimensionarlo. Este problema se resuelve en iOS 10.
Para resolver este problema, solo hazlo con el siguiente código:
self.tableView.tableHeaderView = self.tableView.tableHeaderView;
En iOS 9.x, hacer esto en viewDidLoad
funciona bien:
var frame = headerView.frame
frame.size.height = 11 // New size
headerView.frame = frame
headerView
se declara como @IBOutlet var headerView: UIView!
y conectado en el guión gráfico, donde se coloca en la parte superior de tableView, para funcionar como tableHeaderView.
Encontré que el inicializador initWithFrame de una UIView no respeta adecuadamente el rect que paso. Por lo tanto, hice lo siguiente que funcionó perfectamente:
- (id)initWithFrame:(CGRect)aRect {
CGRect frame = [[UIScreen mainScreen] applicationFrame];
if ((self = [super initWithFrame:CGRectZero])) {
// Ugly initialization behavior - initWithFrame will not properly honor the frame we pass
self.frame = CGRectMake(0, 0, frame.size.width, 200);
// ...
}
}
La ventaja de esto es que está mejor encapsulado en su código de vista.
Es porque el organismo de tableHeaderView.
Debe establecer la altura de UIView antes de establecer tableHeaderView. (Sería mucho más fácil si Apple abre las fuentes de este marco ...)
Establecer la altura para la propiedad de vista de encabezado tableView.tableHeaderView
en viewDidLoad
parece no funcionar, la altura de la vista de encabezado aún no cambia como se esperaba.
Después de luchar contra este problema durante muchos intentos. Descubrí que puede cambiar la altura invocando la lógica de creación de la vista de encabezado dentro del método - (void)didMoveToParentViewController:(UIViewController *)parent
.
Entonces el código de ejemplo sería así:
- (void)didMoveToParentViewController:(UIViewController *)parent {
[super didMoveToParentViewController:parent];
if ( _tableView.tableHeaderView == nil ) {
UIView *header = [[[UINib nibWithNibName:@"your header view" bundle:nil] instantiateWithOwner:self options:nil] firstObject];
header.frame = CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), HeaderViewHeight);
[_tableView setTableHeaderView:header];
}
}
Esto funcionó para mí en iOS 7 y 8. Este código se ejecuta en el controlador de vista de tabla.
[UIView animateWithDuration:0.3 animations:^{
CGRect oldFrame = self.headerView.frame;
self.headerView.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newHeight);
[self.tableView setTableHeaderView:self.headerView];
}];
FYI: He conseguido que esto funcione modificando tableHeaderView y volviéndolo a configurar. En este caso, estoy ajustando el tamaño de tableHeaderView cuando la subvista UIWebView ha terminado de cargarse.
[webView sizeToFit];
CGRect newFrame = headerView.frame;
newFrame.size.height = newFrame.size.height + webView.frame.size.height;
headerView.frame = newFrame;
[self.tableView setTableHeaderView:headerView];
Implementé el cambio de altura animado del encabezado de la tabla para expandirla a la pantalla general cuando se toca. Sin embargo, el código puede ayudar en otros casos:
// Swift
@IBAction func tapped(sender: UITapGestureRecognizer) {
self.tableView.beginUpdates() // Required to update cells.
// Collapse table header to original height
if isHeaderExpandedToFullScreen {
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.scrollView.frame.size.height = 110 // original height in my case is 110
})
}
// Expand table header to overall screen
else {
let screenSize = self.view.frame // "screen" size
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.scrollView.frame.size.height = screenSize.height
})
}
self.tableView.endUpdates() // Required to update cells.
isHeaderExpandedToFullScreen= !isHeaderExpandedToFullScreen // Toggle
}
Obviamente, ahora Apple debería haber implementado UITableViewAutomaticDimension para tableHeaderView & tableFooterView ...
Lo siguiente parece funcionar para mí usando contraint (s) de diseño:
CGSize s = [ self systemLayoutSizeFittingSize : UILayoutFittingCompressedSize ];
CGRect f = [ self frame ];
f.size = s;
[ self setFrame : f ];
Si desea animar condicionalmente los cambios, puede hacer lo siguiente:
- (void) showHeader:(BOOL)show animated:(BOOL)animated{
CGRect closedFrame = CGRectMake(0, 0, self.view.frame.size.width, 0);
CGRect newFrame = show?self.initialFrame:closedFrame;
if(animated){
// The UIView animation block handles the animation of our header view
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
// beginUpdates and endUpdates trigger the animation of our cells
[self.tableView beginUpdates];
}
self.headerView.frame = newFrame;
[self.tableView setTableHeaderView:self.headerView];
if(animated){
[self.tableView endUpdates];
[UIView commitAnimations];
}
}
Tenga en cuenta que la animación tiene dos pliegues:
- La animación de las celdas debajo de la
tableHeaderView
. Esto se hace usandobeginUpdates
yendUpdates
- La animación de la vista de encabezado real. Esto se hace usando un bloque de animación
UIView
.
Para sincronizar esas dos animaciones, animationCurve
debe establecerse en UIViewAnimationCurveEaseInOut
y la duración en 0.3
, que parece ser lo que UITableView usa para su animación.
Actualizar
Creé un proyecto Xcode en gihub, que hace esto. Echa un vistazo al proyecto ResizeTableHeaderViewAnimated
in besi/ios-quickies
Si el headerView personalizado está diseñado con el uso de autolayout y el headerView debe actualizarse después de la búsqueda web o una tarea similar. luego en iOS-Swift hice esto y obtuve mi headerView actualizado usando el siguiente código:
//to reload your cell data
self.tableView.reloadData()
dispatch_async(dispatch_get_main_queue(),{
// this is needed to update a specific tableview''s headerview layout on main queue otherwise it''s won''t update perfectly cause reloaddata() is called
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
Usé la solución @garrettmoon anterior hasta iOS 7.
Aquí hay una solución actualizada basada en @ garrettmoon''s:
- (void)adjustTableHeaderHeight:(NSUInteger)newHeight animated:(BOOL)animated {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:[CATransaction animationDuration]];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
newHeight);
[(UITableView *)self.superview setTableHeaderView:self];
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[(UITableView *)self.superview setTableHeaderView:self];
}
Esta respuesta es antigua y aparentemente no funciona en iOS 7 y versiones posteriores.
Me encontré con el mismo problema, y también quería los cambios para animar, así que hice una subclase de UIView para mi vista de encabezado y agregué estos métodos:
- (void)adjustTableHeaderHeight:(NSUInteger)newHeight{
NSUInteger oldHeight = self.frame.size.height;
NSInteger originChange = oldHeight - newHeight;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
newHeight);
for (UIView *view in [(UITableView *)self.superview subviews]) {
if ([view isKindOfClass:[self class]]) {
continue;
}
view.frame = CGRectMake(view.frame.origin.x,
view.frame.origin.y - originChange,
view.frame.size.width,
view.frame.size.height);
}
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[(UITableView *)self.superview setTableHeaderView:self];
}
Esto esencialmente anima todas las subvistas de UITableView que no son del mismo tipo de clase que la clase de llamada. Al final de la animación, llama a setTableHeaderView en la supervista (UITableView); sin esto, los contenidos de UITableView retrocederán la próxima vez que el usuario se desplace. La única limitación que he encontrado hasta ahora es que si el usuario intenta desplazar el UITableView mientras se desarrolla la animación, el desplazamiento se animará como si la vista del encabezado no se hubiera cambiado de tamaño (no es gran cosa si la animación es rápido).