Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何获取UITableView';什么是可见部分?_Iphone_Ios_Objective C_Uitableview - Fatal编程技术网

Iphone 如何获取UITableView';什么是可见部分?

Iphone 如何获取UITableView';什么是可见部分?,iphone,ios,objective-c,uitableview,Iphone,Ios,Objective C,Uitableview,UITableView提供了方法indexPathsForVisibleRows和visibleCells,但如何获取可见部分?UITableView使用nsindepath存储其单元格。因此,没有用于截面的对象。使用下面的代码,我们可以遍历该表,并使用可见部分的索引执行操作(我不确定为什么需要可见部分,因为可见部分仅表示它们当前在屏幕上,但不管怎样) 我找到了解决办法 第一步,每个部分将显示一个UIView,它是由-(UIView*)tableView:(UITableView*)tableV

UITableView
提供了方法
indexPathsForVisibleRows
visibleCells
,但如何获取可见部分?

UITableView使用nsindepath存储其单元格。因此,没有用于截面的对象。使用下面的代码,我们可以遍历该表,并使用可见部分的索引执行操作(我不确定为什么需要可见部分,因为可见部分仅表示它们当前在屏幕上,但不管怎样)


我找到了解决办法

第一步,每个部分将显示一个UIView,它是由
-(UIView*)tableView:(UITableView*)tableView for HeaderInSection:(NSInteger)部分创建的,将存储到数组中

滚动TableView时,我希望释放不可见的截面视图,因此我需要知道哪个截面可见或不可见,follow函数代码将为此检测,如果视图可见,则释放它

-(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;
}
-(BOOL)isVisibleRect:(CGRect)rect containerView:(UIScrollView*)containerView
{
CGPoint=containerView.contentOffset;
cgzy=点y;
CGFloat py=rect.origin.y+rect.size.height;
if(py-zy by){
返回FALSE;
}
返回TRUE;
}
rect
是节
UIView
的框架;
containerView
UITableView


通过这种方式,我可以获得
UITableView
的可见部分,但我希望SDK可以直接为此提供API

从可见行列表中提取节:

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

另一种解决方案是,在节标题视图的标记中使用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));
            }
        }
    }
}

#定义_TBL_TAG_节(_TAG)(_TAG)|(1或者真正简单的方法是利用valueForKeyPath和NSSet类:

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

基本上,您可以在可见行中获得一个截面值数组,然后用该数组填充一个集合以删除重复项。

2步骤解决方案以在UITableView中获得可见截面:

1) 将标题视图添加到
viewForHeaderInSection

2) 当tableview在
scrollViewDidScroll

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

@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"];
这可能会给您一个具有重复值的数组,但您可以从中进行管理。

for(NSUInteger section=0;sectionfor (NSUInteger section = 0; section < self.tableView.numberOfSections; ++section) {
    UIView *headerView = [self.tableView headerViewForSection:section];
    if (headerView.window) {
        NSLog(@"its visible");
    }
}
UIView*headerView=[self.tableView headerViewForSection:section]; if(headerView.window){ NSLog(“其可见”); } }
Swift版本

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

Swift 4.1您在Swift 4中试用过吗

let sections=tableView.indexPathsForVisibleRows?.map{$0.section}??[]
对于{
打印(字符串(格式:“%d”,节))
}

Swift 4和Swift 5

我们可以执行以下操作,因为空节仍然可以具有可见的标题视图:

extension UITableView {

    var indexesOfVisibleSections: [Int] {
        var indexes = [Int]()
        (0 ..< numberOfSections).forEach {
            let headerRect = (style == .plain ? 
                              rect(forSection: $0) : 
                              rectForHeader(inSection: $0))
            // The "visible part" of the tableView is based on the
            // content offset and the tableView's size.
            let visiblePartOfTableView =
                CGRect(x: contentOffset.x, y: contentOffset.y,
                       width: bounds.size.width, height: bounds.size.height)
            if (visiblePartOfTableView.intersects(headerRect)) {
                indexes.append($0)
            }
        }
        return indexes
    }

}
扩展UITableView{ var IndexOfVisibleSections:[Int]{ var索引=[Int]() (0..
但如果节中没有单元格,则“indexPathsForVisibleRows”方法将返回null…..我想知道节在屏幕上是否可见,然后我可以在动态中释放或创建它,否则它必须保留,这将消耗大量内存…..我在这里添加了一个答案,用于处理没有单元格的节。多么简单回答。谢谢@MikkelSelsøe如果节中没有行,则该节也不可见。。。所以我不确定你说的是不是行不通。你可以有没有节行的节标题。有这样的用例。这个答案解决了这个问题:非常好!我认为一个更简单的改进是使用
@distinctUnionOfObjects
,这样可以节省创建
NSSet
的时间。这就给出了:
[[self.tableView indexPathsForVisibleRows]valueForKeyPath:@“@distinctUnionOfObjects.section”]
。它的swift等价物是什么?如果你在你的答案发布前3个月阅读了我的答案,我已经使用了这项技术,然后使用了一套来消除重复项。@christopherKing,我的错。在发布答案时不要检查。如果第0节中有10行,第1节中有10行,并且它们都在屏幕上,这不是每十次打印一次而不是一次吗?你忘记了零行的部分@没有任何行的VyachaslavGerchicov节被UI框架视为不可见。我不知道你指的是哪个框架,但在我的例子中,节具有节头视图和零行。所以这个部分是可见的,而你的代码对它不起作用。。。如果第0节有10行,第1节有10行,并且它们都在屏幕上,这不是每行打印10次而不是一次吗?@MarkA.Donohoe添加以下行:
let uniqueSections=Array(Set(visibleSections)).sorted()//转换为set会丢失顺序,因此排序
会使您忘记具有零行的部分!您忘记了零行的部分@VyachaslavGerchicov更新了我的答案,以包含可能为空但具有可见标题视图的部分
if let visibleRows = tableView.indexPathsForVisibleRows {
    let visibleSections = visibleRows.map({$0.section})
}
extension UITableView {

    var indexesOfVisibleSections: [Int] {
        var indexes = [Int]()
        (0 ..< numberOfSections).forEach {
            let headerRect = (style == .plain ? 
                              rect(forSection: $0) : 
                              rectForHeader(inSection: $0))
            // The "visible part" of the tableView is based on the
            // content offset and the tableView's size.
            let visiblePartOfTableView =
                CGRect(x: contentOffset.x, y: contentOffset.y,
                       width: bounds.size.width, height: bounds.size.height)
            if (visiblePartOfTableView.intersects(headerRect)) {
                indexes.append($0)
            }
        }
        return indexes
    }

}