2010-11-16 25 views

risposta

1

Io ho la soluzione.

Primo passaggio, ogni sezione mostrerà un UIView creato da - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section, che verrà archiviato nell'array.

Quando si scorre il TableView, voglio liberare la vista in sezione invisibile, quindi ho bisogno di sapere quale sezione è visibile o meno, seguire il codice funzione rileverà per questo scopo, se la vista è visibile, quindi liberarla.

-(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 è il bordo della sezione UIView; containerView è il UITableView)

In questo modo, posso ottenere sezioni visibili del UITableView, ma spero SDK può fornire API per questo scopo direttamente.

7

UITableViews memorizza le proprie celle utilizzando un NSIndexPath. Di conseguenza non vi è alcun oggetto per le sezioni. Usando il seguente codice possiamo attraversare la tabella ed eseguire operazioni usando gli indici delle sezioni visibili (non sono sicuro del perché vuoi sezioni visibili poiché visibile significa solo che sono attualmente sullo schermo, ma qualunque cosa).

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

ma se non le cellule nelle sezioni allora il metodo 'indexPathsForVisibleRows' restituirà nulla ..... – iXcoder

+0

voglio sapere se la sezione è visibile sullo schermo, quindi posso gratis o crearlo in modo dinamico o altro deve essere conservato che mangerà molta memoria ..... – iXcoder

+0

Ho aggiunto una risposta che gestisce le sezioni senza celle qui http://stackoverflow.com/a/23538021/895099 – adamsiton

2

estratto sezioni dalla lista delle righe visibili:

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)] 

Oppure:

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

un'altra soluzione, utilizzare 1 bit nel tag tua sezione di visualizzazione di intestazione, come quella

#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 il modo molto semplice potrebbe essere quella di approfittare della valueForKeyPath e la classe NSSet:

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

Fondamentalmente si ottiene un array di valori di sezione nelle righe visibili e quindi si riempie un set con questo per rimuovere i duplicati.

+1

Che risposta meravigliosamente semplice. Grazie! – ArtSabintsev

+1

Questo non funzionerà per le sezioni senza righe in esse. –

+0

@ MikkelSelsøe Se non ci sono righe nella sezione, la sezione non è visibile neanche ... quindi non sono sicuro che quello che stai dicendo non funzioni. –

1

2 soluzione step per ottenere sezioni visibili in un UITableView:

1) Aggiungere la vista di intestazione per una matrice mutevole in viewForHeaderInSection
2) Aggiornare matrice quando i rotoli Tableview in scrollViewDidScroll

nota l'utilizzo della proprietà tag di tenere il numero della sezione

@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

risposta è molto più semplice e più ordinato con KVC

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

questo potrebbe dare un array con i valori duplicati, ma è possibile gestire da lì.

+0

Se leggi la mia risposta come postata 3 mesi prima del tuo uso già questa tecnica e poi utilizzo un set per eliminare i duplicati . –

+0

@christopherKing, mio ​​male. Non controllare al momento di inviare la risposta. – thesummersign

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

versione Swift

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