Как получить все видимые заголовки заголовка таблицы таблицы

Есть ли способ получить все видимые заголовки разделов?

нечто похожее на экземпляр метода 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 возвращает массив наших видимых заголовков в разделе.