2010-11-16 15 views

Respuesta

1

Tengo la solución.

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

Cuando se desplaza TableView, quiero ver la sección invisible, así que necesito saber qué sección es visible o no, siga el código de función que detectará para este propósito, si la vista es visible, entonces libérela.

-(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 el UITableView)

De esta manera, puedo conseguir secciones visibles de la UITableView, pero espero que el SDK puede proporcionar API para este fin directamente.

7

UITableViews almacenan sus celdas utilizando un NSIndexPath. Como resultado, no hay ningún objeto para las secciones. Utilizando el siguiente código podemos atravesar la tabla y realizar operaciones utilizando los índices de las secciones visibles (no estoy seguro de por qué quieres las secciones visibles, ya que solo son visibles 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 
} 
+3

pero si no hay células en las secciones entonces el método 'indexPathsForVisibleRows' volverá nula ..... – iXcoder

+0

quiero saber si la sección es visible en la pantalla a continuación, que pueda libre o crearlo en la dinámica o de lo contrario tiene que ser retener que se comerá mucha memoria ..... – iXcoder

+0

Agregué una respuesta que maneja secciones sin celdas aquí http://stackoverflow.com/a/23538021/895099 – adamsiton

2

Extracto de las secciones de la lista 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)} 
0

otra solución, use 1 bit en la etiqueta de su sección de vista de encabezado, al igual que

#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)); 
      } 
     } 
    } 
} 
17

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

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

Básicamente se obtiene una matriz de los valores de sección en las filas visibles y luego rellene un conjunto con esto para eliminar los duplicados.

+1

Qué respuesta tan bellamente simple. ¡Gracias! – ArtSabintsev

+1

Esto no funcionará para las secciones sin filas en ellas. –

+0

@ MikkelSelsøe Si no hay filas en la sección, entonces la sección tampoco está visible ... así que no estoy seguro de que lo que está diciendo no funcione. –

1

2 solución de paso para obtener las secciones visibles en un UITableView:

1) Añadir los puntos de vista de cabecera a una matriz mutable en viewForHeaderInSection
2) Actualización de la matriz cuando los rollos Tableview en scrollViewDidScroll

nota el uso de la propiedad tag para mantener el número de 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]; 
} 
1

respuesta es mucho más simple y más limpio con KVC

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

esto podría darle una matriz con valores duplicados, pero puede gestionar desde allí.

+0

Si lee mi respuesta publicada 3 meses antes que la suya, ya uso esta técnica y luego uso un conjunto para deshacerme de los duplicados . –

+0

@christopherKing, mi mal. No revisar en el momento de publicar la respuesta. – thesummersign

1
for (NSUInteger section = 0; section < self.tableView.numberOfSections; ++section) { 
    UIView *headerView = [self.tableView headerViewForSection:section]; 
    if (headerView.window) { 
     NSLog(@"its visible"); 
    } 
} 
6

versión Swift

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