¿Cómo get las secciones visibles de UITableView?

UITableView proporciona los methods indexPathsForVisibleRows y visibleCells , pero ¿cómo puedo get las secciones visibles?

O la manera realmente fácil sería aprovechar valueForKeyPath y la class NSSet:

 NSSet *visibleSections = [NSSet setWithArray:[[self.tableView indexPathsForVisibleRows] valueForKey:@"section"]]; 

Básicamente, obtienes una matriz de valores de sección en las filas visibles y luego rellenas un set con esto para eliminar duplicates.

UITableViews almacena sus células utilizando un NSIndexPath. Como resultado, no hay ningún object para las secciones. Usando el siguiente código podemos recorrer la tabla y realizar operaciones utilizando los índices de las secciones visibles (no estoy seguro de por qué quieres secciones visibles ya que solo visibles significa que están actualmente en la pantalla, pero lo que sea).

 for (NSIndexPath* i in [yourTableViewName indexPathsForVisibleRows]) { NSUInteger sectionPath = [i indexAtPosition:0]; //custom code here, will run multiple times per section for each visible row in the group } 

Versión Swift

 if let visibleRows = tableView.indexPathsForVisibleRows { let visibleSections = visibleRows.map({$0.section}) } 

Extrae las secciones de la list de filas visibles:

 NSArray *indexPathsForVisibleRows = [tableView indexPathsForVisibleRows]; NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet]; for ( NSIndexPath *indexPath in indexPathsForVisibleRows ) { [indexSet addIndex:indexPath.section]; } NSLog(@"indexSet %@",indexSet); // indexSet <NSMutableIndexSet: 0x11a5c190>[number of indexes: 5 (in 1 ranges), indexes: (9-13)] 

O:

 NSArray *indexPathsForVisibleRows = [detailTableView indexPathsForVisibleRows]; NSMutableSet *sectionSet = [NSMutableSet set]; for ( NSIndexPath *indexPath in indexPathsForVisibleRows ) { [sectionSet addObject:[NSNumber numberWithInt:indexPath.section]]; } NSLog(@"sectionSet %@",sectionSet); // sectionSet {(13, 11, 9, 10, 12 )} 

Tengo la solucion

Primer paso, cada sección mostrará una UIView creada por - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section , que se almacenará en array.

Cuando se desplaza el TableView, deseo la vista de la sección invisible, así que necesito saber qué sección es visible o no, el código de function seguirá detectándose para este propósito, si la vista es visible, entonces libérala.

 -(BOOL)isVisibleRect:(CGRect)rect containerView:(UIScrollView*)containerView { CGPoint point = containerView.contentOffset; CGFloat zy = point.y ; CGFloat py = rect.origin.y + rect.size.height; if (py - zy <0) { return FALSE; } CGRect screenRect = containerView.frame; CGFloat by = screenRect.size.height + zy ; if (rect.origin.y > by) { return FALSE; } return TRUE; } 

( rect es el marco de la sección UIView ; containerView es UITableView )

De esta manera, puedo get secciones visibles de UITableView , pero espero que el SDK pueda proporcionar API para este propósito directamente.

Solución de 2 pasos para get las secciones visibles en un UITableView:

1) Agregue las vistas de encabezado a una matriz mutable en viewForHeaderInSection
2) Actualice la matriz cuando la vista de scrollViewDidScroll en scrollViewDidScroll

Observe el uso de la propiedad tag para mantener el número de la sección

 @property (nonatomic, strong, readwrite) NSMutableArray *headerArray; - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 40)]; headerView.backgroundColor = [UIColor greenColor]; headerView.tag = section; [_headerArray addObject:headerView]; return headerView; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self updateHeaderArray]; NSLog(@"------------"); for (UIView *view in _headerArray) { NSLog(@"visible section:%d", view.tag); } } - (void)updateHeaderArray { // remove invisible section headers NSMutableArray *removeArray = [NSMutableArray array]; CGRect containerRect = CGRectMake(_tableView.contentOffset.x, _tableView.contentOffset.y, _tableView.frame.size.width, _tableView.frame.size.height); for (UIView *header in _headerArray) { if (!CGRectIntersectsRect(header.frame, containerRect)) { [removeArray addObject:header]; } } [_headerArray removeObjectsInArray:removeArray]; } 

La respuesta es mucho más sencilla y clara con kvc

 NSArray *visibleSections = [self.tableView.indexPathsForVisibleRows valueForKey:@"section"]; 

esto podría proporcionarle una matriz con valores duplicates, pero puede administrar desde allí.

Otra solución, use 1 bit en la label de la vista de encabezado de sección, así

 #define _TBL_TAG_SECTION(_TAG) ((_TAG)|(1<<30)) #define _TBL_TAG_CLEAR(_TAG) ((_TAG)&((1<<30)-1)) #define _TBL_TAG_IS_SECTION(_TAG) ((_TAG)>>30) - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { // alloc header view UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)]; header.tag = _TBL_TAG_SECTION(section); return header; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGRect r = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, CGRectGetWidth(scrollView.frame), CGRectGetHeight(scrollView.frame)); for (UIView *v in [_tableView subviews]) { if ( CGRectIntersectsRect(r, v.frame) ) { if ( _TBL_TAG_IS_SECTION(v.tag) ) { NSLog(@"visible section tag %d", _TBL_TAG_CLEAR(v.tag)); } } } } 
 for (NSUInteger section = 0; section < self.tableView.numberOfSections; ++section) { UIView *headerView = [self.tableView headerViewForSection:section]; if (headerView.window) { NSLog(@"its visible"); } }