UITableView
provides the methods indexPathsForVisibleRows
and visibleCells
, but how can I get the visible sections?
UITableViews store their cells using an NSIndexPath. As a result there is no object for sections. Using the following code we can traverse the table and perform operations using the indexes of visible sections (I'm not sure why you want visible sections since visible only means they are currently on the screen, but whatever).
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
}
I have got the solution.
First step, each section will show a UIView that created by - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
, that will be stored into array.
When the TableView is scrolled , I want free the invisible section view, so I need know which section is visible or not, follow function code will detect for this purpose, if the view is visible then free it.
-(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
is the frame of the section UIView
; containerView
is the UITableView
)
In this way, I can get visible sections of the UITableView
, but I hope the SDK can provide API for this purpose directly.
Have you tried this in Swift 4?
let sections = tableView.indexPathsForVisibleRows?.map { $0.section } ?? []
for section in sections {
print(String(format: "%d", section))
}
Answer is a lot simpler and neater with kvc
NSArray *visibleSections = [self.tableView.indexPathsForVisibleRows valueForKey:@"section"];
this might give you an array with duplicate values but you can manage from there.
another solution, use 1 bit in your section header view's tag, like that
#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));
}
}
}
}