ios uitableview ios8

Obtenga la referencia de la celda bajo heightForRowAtIndexPath: en iOS 8



uitableview ios8 (4)

Como dijiste, el método delegado heightForRowAtIndexPath no te dará la altura dinámica de las filas cuando se llame automáticamente. En su lugar, debe llamarlo explícitamente como: [self delegateMethod] es decir [self tableView:tableView cellForRowAtIndexPath:indexPath];

Si tiene su tableView principal declarado como un IBOutlet como myTableView , entonces incluso llamar a [self.myTableView cellForRowAtIndexPath:indexPath] no funcionará.

He probado el código y esto está funcionando para mí:

Dentro de MainTableViewController.m :

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 7; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tableViewCellMain"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"tableViewCellMain"]; } UITableView *tableViewChild = [[UITableView alloc] initWithFrame:CGRectMake(cell.frame.origin.x, cell.frame.origin.y, tableView.frame.size.width, tableView.frame.size.height) style:UITableViewStylePlain]; [self.cls setNumberOfRows:indexPath.row+1]; [tableViewChild setDelegate:self.cls]; [tableViewChild setDataSource:self.cls]; [tableViewChild setSeparatorStyle:UITableViewCellSeparatorStyleNone]; [tableViewChild setScrollEnabled:NO]; [tableViewChild reloadData]; [cell addSubview:tableViewChild]; return cell; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; CGFloat height = cell.frame.size.height; for (int i=0; i<cell.subviews.count; i++) { UITableView *childTableView = (UITableView*) [cell.subviews lastObject]; height = childTableView.contentSize.height; } NSLog(@"%f",height); return height; }

He establecido otra clase como delegado para que childTableView obtenga sus datos.

Dentro de ChildTableViewController.m :

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.numberOfRows; } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tableViewCellChild"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"tableViewCellChild"]; } [cell.textLabel setText:[NSString stringWithFormat:@"%ld",indexPath.row]]; UIColor *cellTextColor = [UIColor blackColor]; switch (indexPath.row) { case 0: cellTextColor = [UIColor redColor]; break; case 1: cellTextColor = [UIColor greenColor]; break; case 2: cellTextColor = [UIColor blueColor]; break; case 3: cellTextColor = [UIColor magentaColor]; break; case 4: cellTextColor = [UIColor purpleColor]; break; default: break; } [cell.textLabel setTextColor:cellTextColor]; [tableView sizeToFit]; return cell; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 30; }

Y obtendrá el trabajo como se muestra en esta imagen:

Mi guión gráfico se ve así:

Puede usar cualquier forma para producir el contenido dinámico para mainTableView y no es necesario usar otra clase para childTableView .

Actualmente estoy trabajando en un proyecto donde he incrustado un UITableView dentro de UITableViewCell .

Lo que necesito hacer es deshabilitar el desplazamiento de UITableView y hacer que UITableView ajuste al tamaño de todas las filas. Pero como el UITableView hereda de UIScrollView , el uso de Autolayout no obliga a UITableView a hacer que la altura de la celda dependa de su contentSize (no de marco) al devolver UITableViewAutomaticDimension .

Solución iOS 7

Esto fue fácil de lograr hasta iOS 7, ya que obtengo la referencia de la celda bajo heightForRowAtIndexPath: usando el siguiente código:

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; int height = cell.tableView.contentSize.height; return height;

pero en iOS 8 da BAD_ACCESS ya que iOS 8 llama a heightForRowAtIndexPath: antes de que se haya llamado a cellForRowAtIndexPath:

Enfoque iOS 8

Declara una propiedad para mantener la referencia de la celda:

@property (strong, nonatomic) UITableViewCell *prototypeCell

Use un método para guardar la referencia de celda actual a la propiedad para usarla:

- (id)prototypeCellatIndexPath:(NSIndexPath *)indexPath { NSString *cellID = @"MyCell"; if (!_prototypeCell) { _prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:cellID]; } return _prototypeCell; }

Obtenga UITableView de la UITableViewCell del prototipo y de su contenido Tamaño Obtenga la altura y la devuelvo bajo heighForRowAtIndexPath: del siguiente método:

-(int)heightForThreadAtIndexPath:(NSIndexPath *)indexPath { _prototypeCell = [self prototypeCellatIndexPath:indexPath]; [_prototypeCell.contentView setNeedsLayout]; [_prototypeCell.contentView layoutIfNeeded]; int footer = [_prototypeCell.tableView numberOfSections]*_prototypeCell.tableView.sectionFooterHeight; int header = [_prototypeCell.tableView numberOfSections]*_prototypeCell.tableView.sectionHeaderHeight; int height = ceilf(_prototypeCell.tableView.contentSize.height) + _prototypeCell.tableView.contentOffset.y + _prototypeCell.tableView.contentInset.bottom + _prototypeCell.tableView.contentInset.top + header + footer; NSLog(@"%i, %i", (int)ceilf(_prototypeCell.tableView.contentSize.height), height); return height; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return [self heightForThreadAtIndexPath:indexPath]; }

Problema

El contentSize.height que obtengo de prototypeCell está equivocado y no coincide con el UITableView real de la UITableView , pero cuando registro el contentSize real en la clase CustomCell , muestra el contentSize correcto, que difiere del de prototypeCell. .

Esto me hace pensar que tal vez debería intentar sacar la celda en un estado específico para obtener el ContentSize correcto, pero los registros muestran los mismos valores.

He estado investigando mucho y probando diferentes ideas, pero ninguna ha funcionado hasta ahora. No sé si alguien ha intentado lograr algo similar a mí y ha resuelto esto. Será muy bueno si me das una idea o algo así.


Configuré otra respuesta, configuré todo completamente dinámico y no puedo reproducir su problema: Aquí hay un repositorio: https://bitbucket.org/Kettu/dynamiccellfrorow . Lo que hago es llamar a recargar datos cuando awakeForNib que awakeForNib calcule todas las filas de una mosca y el valor final se puede encontrar como en iOS 7 en scrollView contentSize.

Tenga en cuenta que dado que el número de filas y la altura son completamente aleatorios en este proyecto de demostración, este se volverá a cargar y parpadeará cada vez que la celda sea reutilizable. No debería ocurrir en datos reales.


No estoy seguro de si eso te ayudó o no, pero tuve que hacer algo como esto antes y terminé en UICollectionView incrustado con desplazamiento vertical en la celda para que actúe como tableview pero otra vista no UITableView y eso me permite controlar cada uno por separado del otro

Espero que este consejo te ayude buena suerte.


Puede usar su enfoque de iOS 7 también en iOS 8, lo único que se cambió es que no puede usar el delegate desde su método heightForRowAtIndexPath: pero puede llamar al cellForRowAtIndexPath: real en su controlador, así que cambie de línea:

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

alinear:

UITableViewCell* cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];

Y debería funcionar.