Есть ли способ получить все видимые заголовки разделов?
нечто похожее на экземпляр метода UITableView visibleCells.
Есть ли способ получить все видимые заголовки разделов?
нечто похожее на экземпляр метода UITableView visibleCells.
Проблема с использованием 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
Мне действительно понравилось решение @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
}
}
Для таблицы с обычным стилем вы можете получить видимые строки. Из этого получим набор видимых разделов. И из этого вы получите заголовки заголовков раздела из таблицы.
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% для таблицы сгруппированных стилей.
Решение 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
}
}
В этом случае, я думаю, вы установили cell.tag
в текущий раздел (indexPath.section
) в cellForRowAtIndexPath
и используете метод visibleCells
, как вы описали, и headerViewForSection
.
чтобы получить текущие видимые разделы, вы можете получить его, проверив текущую секцию индексного пути видимых ячеек, чтобы эта функция могла вернуться к 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;
Быстрый просмотр документа UITableView дает нам indexPathsForVisibleRows и объединение его с картой дает нам необходимый массив:
tableView.indexPathsForVisibleRows.map{ tableView.headerView(forSection: $0.section) }
map возвращает массив наших видимых заголовков в разделе.