2013-03-04 9 views

Odpowiedz

13

Problem z używaniem indexPathsForVisibleRows polega na tym, że nie zawiera sekcji bez żadnych wierszy. Aby uzyskać całą widoczną sekcję, w tym puste sekcje, musisz sprawdzić poprawność sekcji i porównać ją z contentOffset tabeli.

Należy również zwrócić uwagę na różnicę między prostym stylem a ruchomymi sekcjami i zgrupowanym stylem bez ruchomych sekcji.

zrobiłem kategorię, która obsługuje tej kalkulacji:

@interface UITableView (VisibleSections) 

// Returns an array of NSNumbers of the current visible section indexes 
- (NSArray *)indexesOfVisibleSections; 
// Returns an array of UITableViewHeaderFooterView objects of the current visible section headers 
- (NSArray *)visibleSections; 

@end 

@implementation UITableView (VisibleSections) 

- (NSArray *)indexesOfVisibleSections { 
    // Note: We can't just use indexPathsForVisibleRows, since it won't return index paths for empty sections. 
    NSMutableArray *visibleSectionIndexes = [NSMutableArray arrayWithCapacity:self.numberOfSections]; 
    for (int i = 0; i < self.numberOfSections; i++) { 
     CGRect headerRect; 
     // In plain style, the section headers are floating on the top, so the section header is visible if any part of the section's rect is still visible. 
     // In grouped style, the section headers are not floating, so the section header is only visible if it's actualy rect is visible. 
     if (self.style == UITableViewStylePlain) { 
      headerRect = [self rectForSection:i]; 
     } else { 
      headerRect = [self rectForHeaderInSection:i]; 
     } 
     // The "visible part" of the tableView is based on the content offset and the tableView's size. 
     CGRect visiblePartOfTableView = CGRectMake(self.contentOffset.x, self.contentOffset.y, self.bounds.size.width, self.bounds.size.height); 
     if (CGRectIntersectsRect(visiblePartOfTableView, headerRect)) { 
      [visibleSectionIndexes addObject:@(i)]; 
     } 
    } 
    return visibleSectionIndexes; 
} 

- (NSArray *)visibleSections { 
    NSMutableArray *visibleSects = [NSMutableArray arrayWithCapacity:self.numberOfSections]; 
    for (NSNumber *sectionIndex in self.indexesOfVisibleSections) { 
     UITableViewHeaderFooterView *sectionHeader = [self headerViewForSection:sectionIndex.intValue]; 
     [visibleSects addObject:sectionHeader]; 
    } 

    return visibleSects; 
} 

@end 
4

Na stole w stylu prostym, można uzyskać widoczne wiersze. Z tego uzyskać zestaw widocznych sekcji. I z tego uzyskać widoki nagłówka sekcji z tabeli.

NSArray *visibleRows = [self.tableView indexPathsForVisibleRows]; 
NSMutableIndexSet *sections = [[NSMutableIndexSet alloc] init]; 
for (NSIndexPath *indexPath in visibleRows) { 
    [sections addIndex:indexPath.section]; 
} 

NSMutableArray *headerViews = [NSMutableArray array]; 
[sections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 
    UIView *view = [self.tableView headerViewForSection:idx]; 
    [headerViews addObject:view]; 
}]; 

Uwaga: kod nie testowany - może zawierać literówki. To nie zadziała w 100% dla zgrupowanej tabeli stylów.

+1

nie działa, jeśli sekcja nie ma wierszy –

+1

@PeterLapisu True, ale nie powinieneś pokazywać nagłówka sekcji dla sekcji bez wierszy, więc nie będzie to problemem. – rmaddy

+1

zależy od przypadku, właśnie napotkałem taką sytuację :)) –

1

W tym przypadku, myślę, że można ustawić cell.tag do bieżącej sekcji (indexPath.section) w cellForRowAtIndexPath i użyć metody visibleCells jak opisane i headerViewForSection.

6

bardzo lubiłem @ rozwiązanie adamsiton i skończyło się tłumacząc ją do szybkich. Oto jest, FYI.

Zadzwoniłem plik UITableView + VisibleSections.swift

import UIKit 

public extension UITableView { 

    var indexesOfVisibleSections: [Int] { 
     // Note: We can't just use indexPathsForVisibleRows, since it won't return index paths for empty sections. 
     var visibleSectionIndexes = [Int]() 

     for i in 0..<numberOfSections { 
      var headerRect: CGRect? 
      // In plain style, the section headers are floating on the top, so the section header is visible if any part of the section's rect is still visible. 
      // In grouped style, the section headers are not floating, so the section header is only visible if it's actualy rect is visible. 
      if (self.style == .plain) { 
       headerRect = rect(forSection: i) 
      } else { 
       headerRect = rectForHeader(inSection: i) 
      } 
      if headerRect != nil { 
       // The "visible part" of the tableView is based on the content offset and the tableView's size. 
       let visiblePartOfTableView: CGRect = CGRect(x: contentOffset.x, y: contentOffset.y, width: bounds.size.width, height: bounds.size.height) 
       if (visiblePartOfTableView.intersects(headerRect!)) { 
        visibleSectionIndexes.append(i) 
       } 
      } 
     } 
     return visibleSectionIndexes 
    } 

    var visibleSectionHeaders: [UITableViewHeaderFooterView] { 
     var visibleSects = [UITableViewHeaderFooterView]() 
     for sectionIndex in indexesOfVisibleSections { 
      if let sectionHeader = headerView(forSection: sectionIndex) { 
       visibleSects.append(sectionHeader) 
      } 
     } 

     return visibleSects 
    } 
} 
2

Rozwiązanie Benjamin Wheeler jest doskonałym rozwiązaniem Swift. Rozwiązałem problem z powodu nowej składni Swift i zmodyfikowałem go tak, aby pasował do właściwości .visibleCells dostarczanej przez domyślną implementację UITableView.

extension UITableView { 

    /// The table section headers that are visible in the table view. (read-only) 
    /// 
    /// The value of this property is an array containing UITableViewHeaderFooterView objects, each representing a visible cell in the table view. 
    /// 
    /// Derived From: [http://stackoverflow.com/a/31029960/5191100](http://stackoverflow.com/a/31029960/5191100) 
    var visibleSectionHeaders: [UITableViewHeaderFooterView] { 
     get { 
      var visibleSects = [UITableViewHeaderFooterView]() 

      for sectionIndex in indexesOfVisibleSections() { 
       if let sectionHeader = self.headerViewForSection(sectionIndex) { 
        visibleSects.append(sectionHeader) 
       } 
      } 

      return visibleSects 
     } 
    } 

    private func indexesOfVisibleSections() -> Array<Int> { 
     // Note: We can't just use indexPathsForVisibleRows, since it won't return index paths for empty sections. 
     var visibleSectionIndexes = Array<Int>() 

     for (var i = 0; i < self.numberOfSections; i++) { 
      var headerRect: CGRect? 
      // In plain style, the section headers are floating on the top, 
      // so the section header is visible if any part of the section's rect is still visible. 
      // In grouped style, the section headers are not floating, 
      // so the section header is only visible if it's actual rect is visible. 
      if (self.style == .Plain) { 
       headerRect = self.rectForSection(i) 
      } else { 
       headerRect = self.rectForHeaderInSection(i) 
      } 

      if headerRect != nil { 
       // The "visible part" of the tableView is based on the content offset and the tableView's size. 
       let visiblePartOfTableView: CGRect = CGRect(
        x: self.contentOffset.x, 
        y: self.contentOffset.y, 
        width: self.bounds.size.width, 
        height: self.bounds.size.height 
       ) 

       if (visiblePartOfTableView.intersects(headerRect!)) { 
        visibleSectionIndexes.append(i) 
       } 
      } 
     } 

     return visibleSectionIndexes 
    } 
} 
1

uzyskać bieżące widoczne sekcje, u może dostać od sprawdzenia aktualnych widocznych komórek indexpath odcinek, więc funkcja ta mogła powrócić do U widoczne sekcje

- (NSArray *)indexesOfVisibleSections { 

    NSMutableArray *visibleSections = [NSMutableArray array]; 

    for (UITableViewCell * cell in [self.tableView visibleCells]) { 
     if (![visibleSections containsObject:[NSNumber numberWithInteger:[self.tableView indexPathForCell:cell].section]]) { 
      [visibleSections addObject:[NSNumber numberWithInteger:[self.tableView indexPathForCell:cell].section]]; 
     } 
    } 

    return visibleSections; 
} 

oraz uzyskać dostęp do widoku przekroju, u mogą korzystać

- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section; 
+0

nie uwzględnia nagłówka, który nie zawiera żadnych komórek – kgaidis

+0

@kgaidis przetestowałeś go? logika tutaj, że dostaje widoczną sekcję komórki, niezależnie od jej typu, więc jeśli masz 3 sekcje, każda z nich ma 1 rząd, to sprawdza widoczną tablicę wierszy i pobiera te sekcje wierszy i dodaje ją do tablicy widocznych sekcji, nie ma to nic wspólnego z typem nagłówka, widokiem lub komórką – Mortgy

+0

"Każdy ma 1 wiersz". Tam się nie udaje. Może istnieć sekcja z widocznym widokiem nagłówka bez komórek. Jeśli sekcja nie ma żadnych komórek, nie będzie ona częścią "widocznych komórek", na czym całkowicie opiera się ten algorytm. – kgaidis

0

szybkie spojrzenie na dokumentacji UITableView daje nam indexPathsForVisibleRows i łącząc ją z mapą daje nam tablicę my Ne ed:

tableView.indexPathsForVisibleRows.map{ tableView.headerView(forSection: $0.section) } 

mapa zwraca tablicę naszych widocznych nagłówków w sekcji.

Powiązane problemy