如何获得UITableView的可见部分?

UITableView提供了方法indexPathsForVisibleRowsvisibleCells ,但我怎样才能得到可见的部分?

或者真正简单的方法是利用valueForKeyPath和NSSet类:

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

基本上,你可以在可见的行中得到一个数组的值,然后用这个来填充一个集合来删除重复项。

UITableViews使用NSIndexPath存储它们的单元格。 因此没有对象的部分。 使用下面的代码,我们可以遍历表格,并使用可见部分的索引执行操作(我不知道为什么你想要可见部分,因为可见仅意味着它们当前在屏幕上,但不pipe)。

 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 } 

Swift版本

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

从可见行列表中提取部分:

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

要么:

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

我有解决scheme。

第一步,每个部分都会显示一个由- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section创build的- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section ,它将被存储到数组中。

当TableView被滚动时,我想要释放不可见的部分视图,所以我需要知道哪个部分是可见或不可见的,跟随的function代码将检测到这个目的,如果视图是可见的,那么释放它。

 -(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; } 

rectUIView部分的框架; containerViewUITableView

这样,我可以看到UITableView可见部分,但是我希望SDK可以直接为此提供API。

2步骤解决scheme来获取UITableView中的可见部分:

1)将标题视图添加到viewForHeaderInSection的可变数组中
2)当tableview在scrollViewDidScroll滚动时更新数组

请注意使用标签属性来保存节号

 @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]; } 

答案是kvc更简单和更整洁

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

这可能会给你一个重复值的数组,但你可以从那里pipe理。

另一种解决scheme,就像在你的部分标题视图的标签中使用1位

 #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)); } } } } 
 for (NSUInteger section = 0; section < self.tableView.numberOfSections; ++section) { UIView *headerView = [self.tableView headerViewForSection:section]; if (headerView.window) { NSLog(@"its visible"); } }