跟踪UITableViewCell子视图的坐标

当UITableviewCell的子视图到达屏幕上的某个点时,我想发起一个事件,比如说当它的origin.y达到44点时。 当它达到那个点时,知道它是否被上下滚动也是很好的。 我在子视图的框架上玩KVO,但这似乎固定在单元格,所以没有改变。 这个任务可能吗?

UITableViewCell的垂直位置由其frame属性定义,该属性表示该单元在其超级视图UITableView中的位置和大小。 通常,每当UITableView从其委托中为特定索引path请求单元格时,单元格的frame属性只会更改一次。 就这样,UITableView获取一个单元格,将其放置在自身中,并且该单元格不会改变,直到存储在UITableView的bounds属性中的矩形停止包含存储在该单元格的frame属性中的矩形。 在这种情况下,UITableView将该单元标记为隐藏,并将其放置到可重用单元池中。

由于滚动的过程本质上不是重新定位子视图 – 它只是一个移动UITableView的bounds视口的奇怪幻象 – 常量观察UITableViewCell的属性是毫无意义的。

此外,UITableViewCell子视图的frame属性也代表了它的容器UITableViewCell中的子视图的位置和大小。 滚动也不会改变。

你需要观察UITableView bounds属性的变化,这也是由contentOffset代表的。 UITableView碰巧是UIScrollView的子类,所以你可以使用它的委托方法,比如-scrollViewDidScroll:就像这个简单的例子:


插图


 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { UITableView *tableView = (UITableView *)scrollView; // current position CGFloat currentY = tableView.bounds.origin.y; // current inset CGFloat currentInset = tableView.contentInset.top; // trigger line position CGFloat triggerY = currentInset + currentY + kYourTriggerPosition; // nice visual mark UIView *line = [tableView viewWithTag:88]; if (!line) { line = [[UIView alloc] initWithFrame:CGRectZero]; line.tag = 88; line.backgroundColor = [UIColor redColor]; [tableView addSubview:line]; } line.frame = CGRectMake(0, triggerY, tableView.bounds.size.width, 1); // determine scroll direction BOOL scrollingUp = currentY > self.previousY; // all visible cells NSArray *visibleCells = tableView.visibleCells; [visibleCells enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger idx, BOOL *stop) { // subview UIView *subview = [cell viewWithTag:kYourSubviewTag]; // subview frame rect in UITableView bounds CGRect subviewRect = [subview convertRect:subview.frame toView:tableView]; // trigger line within subview? BOOL triggered = (CGRectGetMinY(subviewRect) <= triggerY) && (CGRectGetMaxY(subviewRect) >= triggerY); if (triggered) { NSIndexPath *indexPath = [tableView indexPathForCell:cell]; NSLog(@"moving %@, triggered for cell at [%2d:%2d]", @[@"down", @"up"][scrollingUp], indexPath.section, indexPath.row); [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } }]; // save current position for future use self.previousY = currentY; } 

cellForRowAtIndexPathtableView.visibleCells覆盖UITableViewCell subview ,然后在该subview上调用convertRectToView:

convertRectToView:允许您在不同的坐标系上进行翻译。 例如,您可以通过在其viewController.view superview viewController.viewframe转换为viewController.view来检测subview在屏幕上的显示viewController.view

更多: Apple文档

由于我不能评论我正在写作答复

更改要求的答案。

下面是我认为它可以完成,你需要有你的自定义UITableViewCell有一个function,可以采取坐标(再次基于你的逻辑,如果你只是想要一个单元格刚刚触及边界的交集,或者如果它必须在一个框架中的一个精确位置),所以你的函数将采取坐标,并会返回一个真实的和假的,如果它会告诉你,如果条件满足,在你的cellForTable函数你调用函数UITableView单元格来检查你的条件是否被满足,如果它在你的视图中,你在确切的位置创build一个子视图。 你也可以修改这个函数来返回你精确的框架坐标,这样你就可以使用它们来创build一个子视图\

这里有一个简单的方法,如果只有一个没有节标题的节,你可以使用这个方法。

添加到您的实施:

 CGFloat lastContentOffSet; 

然后添加这个滚动视图的委托方法,因为tableview也是一个滚动视图。

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat cellHeight = 50; CGFloat touchingPoint = 44.0f; NSInteger rowNo = floor(scrollView.contentOffset.y / cellHeight); NSInteger startPoint = (rowNo * cellHeight); if (scrollView.contentOffset.y > lastContentOffSet) { NSLog(@"Row %ld scrolled down", (long)rowNo); if (scrollView.contentOffset.y > startPoint + touchingPoint) { // Do something here NSLog(@"Do something here"); } } else { NSLog(@"Row %ld scrolled up", (long)rowNo); if (scrollView.contentOffset.y > startPoint + touchingPoint) { // Do something here NSLog(@"Do something here"); } } lastContentOffSet = scrollView.contentOffset.y; } 

根据你的tableview单元格和子视图与单元格之间的距离改变cellheight的值。

让我知道这个代码是否有帮助。 🙂