is there a way to get all the section header views that are visible?
something similar to UITableView\'s visibleCells instance method..
to get the current visible sections, u could get it by checking the current visible cells indexpath section, so this function could return to u the visible sections
- (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;
}
And to access section view , u can use
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section;
I really liked @adamsiton's solution and I ended up translating it to swift. Here it is, FYI.
I called the file 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
}
}
A quick look at the UITableView documentation gives us the indexPathsForVisibleRows and combining it with map gives us the array we need:
tableView.indexPathsForVisibleRows.map{ tableView.headerView(forSection: $0.section) }
map returns the array of our visible headers-in-section.
For a plain style table, you can get the visible rows. From those, get the set of visible sections. And from that, get the section header views from the table.
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];
}];
Note: code not tested - may contain typos. This won't work 100% for a grouped style table.