Как получить все видимые заголовки заголовка таблицы таблицы
Есть ли способ получить все видимые заголовки разделов?
нечто похожее на экземпляр метода UITableView visibleCells.
Ответы
Ответ 1
Проблема с использованием indexPathsForVisibleRows заключается в том, что он не включает разделы без каких-либо строк. Чтобы получить весь видимый раздел, включая пустые разделы, вы должны проверить прямоугольник раздела и сравнить его с содержимым. Создать таблицу.
Вы также должны обратить внимание на разницу между обычным стилем с плавающими разделами и сгруппированным стилем без плавающих разделов.
Я сделал категорию, которая поддерживает этот расчет:
@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 rect is still visible.
// In grouped style, the section headers are not floating, so the section header is only visible if it 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 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
Ответ 2
Мне действительно понравилось решение @adamsiton, и я закончил перевод его быстрым. Вот он, FYI.
Я назвал файл 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 rect is still visible.
// In grouped style, the section headers are not floating, so the section header is only visible if it 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 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
}
}
Ответ 3
Для таблицы с обычным стилем вы можете получить видимые строки. Из этого получим набор видимых разделов. И из этого вы получите заголовки заголовков раздела из таблицы.
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];
}];
Примечание: код не проверен - может содержать опечатки. Это не будет работать на 100% для таблицы сгруппированных стилей.
Ответ 4
Решение Benjamin Wheeler - отличное решение Swift. Я исправил проблему из-за нового синтаксиса Swift и изменил его в соответствии с свойством .visibleCells, предоставленным реализацией по умолчанию 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 rect is still visible.
// In grouped style, the section headers are not floating,
// so the section header is only visible if it 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 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
}
}
Ответ 5
В этом случае, я думаю, вы установили cell.tag
в текущий раздел (indexPath.section
) в cellForRowAtIndexPath
и используете метод visibleCells
, как вы описали, и headerViewForSection
.
Ответ 6
чтобы получить текущие видимые разделы, вы можете получить его, проверив текущую секцию индексного пути видимых ячеек, чтобы эта функция могла вернуться к u видимым разделам
- (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;
}
И чтобы получить доступ к просмотру раздела, вы можете использовать
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section;
Ответ 7
Быстрый просмотр документа UITableView дает нам indexPathsForVisibleRows и объединение его с картой дает нам необходимый массив:
tableView.indexPathsForVisibleRows.map{ tableView.headerView(forSection: $0.section) }
map возвращает массив наших видимых заголовков в разделе.