Как получить видимые разделы UITableView?
UITableView
предоставляет методы indexPathsForVisibleRows
и visibleCells
, но как я могу получить видимые разделы?
Ответы
Ответ 1
У меня есть решение.
На первом этапе в каждом разделе будет показан UIView, созданный - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
, который будет сохранен в массиве.
Когда прокручивается TableView, я хочу освободить невидимый раздел, поэтому мне нужно знать, какая секция видна или нет, после этого код функции будет обнаружен для этой цели, если вид будет виден, тогда освободите его.
-(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
- это кадр раздела UIView
; containerView
- UITableView
)
Таким образом, я могу получить видимые разделы UITableView
, но я надеюсь, что SDK может напрямую предоставить API для этой цели.
Ответ 2
Или очень простой способ - воспользоваться преимуществами valueForKeyPath и классом NSSet:
NSSet *visibleSections = [NSSet setWithArray:[[self.tableView indexPathsForVisibleRows] valueForKey:@"section"]];
В основном вы получаете массив значений раздела в видимых строках, а затем заполняете набор, чтобы удалить дубликаты.
Ответ 3
UITableViews хранят свои ячейки с помощью NSIndexPath. В результате нет объектов для разделов. Используя следующий код, мы можем перемещаться по таблице и выполнять операции с использованием индексов видимых разделов (я не уверен, почему вы хотите видеть видимые разделы, так как они видны только потому, что они в настоящее время находятся на экране, но что угодно).
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
}
Ответ 4
Быстрая версия
if let visibleRows = tableView.indexPathsForVisibleRows {
let visibleSections = visibleRows.map({$0.section})
}
Ответ 5
Извлеките разделы из списка видимых строк:
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 )}
Ответ 6
2-х шаговое решение для получения видимых разделов в UITableView:
1) Добавьте представления заголовков в изменяемый массив в viewForHeaderInSection
2) Обновите массив при прокрутке таблицы в 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];
}
Ответ 7
Ответ намного проще и аккуратно с kvc
NSArray *visibleSections = [self.tableView.indexPathsForVisibleRows valueForKey:@"section"];
это может дать вам массив с повторяющимися значениями, но вы можете управлять оттуда.
Ответ 8
for (NSUInteger section = 0; section < self.tableView.numberOfSections; ++section) {
UIView *headerView = [self.tableView headerViewForSection:section];
if (headerView.window) {
NSLog(@"its visible");
}
}
Ответ 9
другое решение, используйте 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));
}
}
}
}
Ответ 10
Swift 4.1 🔸
self.sections.indices.forEach{ (i:Int) in
let section:UIView? = self.tableView(self, viewForHeaderInSection: i)
}
Ответ 11
Вы пробовали это в Swift 4?
let sections = tableView.indexPathsForVisibleRows?.map { $0.section } ?? []
for section in sections {
print(String(format: "%d", section))
}