带有一个可见单元格的UITableView:确定哪个最明显

时间:2014-12-11 03:43:59

标签: ios objective-c uitableview

在任何给定时间给定一个具有单个可见单元格的UITableView,如何在滚动表格视图时确定哪个单元格最多

我知道通过这样做可以获得一系列可见细胞:

NSArray *paths = [tableView indexPathsForVisibleRows];

然后通过执行以下操作获取最后一个单元格(或第一个或其他单元格):

UITableViewCell* cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:[paths lastObject]];

但是如何比较所有可见细胞并确定它们中哪一个最为可见?

6 个答案:

答案 0 :(得分:4)

以下逻辑将为您提供滚动结尾处最明显的单元格:

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    CGRect visibleRect = (CGRect){.origin = self.tableView.contentOffset, .size = self.tableView.bounds.size};
    CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
    NSIndexPath *visibleIndexPath = [self.tableView indexPathForRowAtPoint:visiblePoint];

}

答案 1 :(得分:3)

根据您返回的路径数量,算法会有所不同:

  • 如果只有一条路径,那就是那里最可见的小区
  • 如果有三条或更多条路径,则中间的任何单元格(即除第一条和最后一条之外的所有单元格)均可见
  • 如果恰好有两个单元格,请找到在父视图 * 中分隔两者的行的位置,并计算两个距离 - 从上到中和从中到下。如果顶部到中间更大,则顶部单元格最明显。如果中间到底部更大,那么第二个单元格更加明显。否则,两个单元格同样可见。

* 中点位置是第二个单元格的底部。顶部和底部位置是表格视图的顶部和底部。

答案 2 :(得分:1)

基于@ Sebyddd的答案的快速解决方案:

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
  scrollToMostVisibleCell()
}

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
  if !decelerate{
    scrollToMostVisibleCell()
  }
}

func scrollToMostVisibleCell(){
  let visibleRect = CGRect(origin: tableView.contentOffset, size: tableView.bounds.size)
  let visiblePoint = CGPoint(x: CGRectGetMidX(visibleRect), y: CGRectGetMidY(visibleRect))
  let visibleIndexPath: NSIndexPath = tableView.indexPathForRowAtPoint(visiblePoint)!

  tableView.scrollToRowAtIndexPath(visibleIndexPath, atScrollPosition: .Top, animated: true)
}

答案 3 :(得分:0)

您可以使用表格视图的rectForRowAtIndexPath:来获取每个可见单元格的框架,然后将它们(CGRectOffset)偏移-contentOffset.y以考虑滚动,然后将它们与表格视图的bounds可以查看每个单元格在表格视图中的可见程度。

答案 4 :(得分:0)

以下逻辑将为您提供UITableViewCell,每当用户停止滚动时,UITableViewCell就会在UITableView中显示最为明显或最重要的位置。希望这种逻辑可以帮助某人。

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
    {
        if (isScrollingStart)
        {
            isScrollingStart=NO;
            isScrollingEnd=YES;
            [self scrollingStopped];
        }
    }
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{

    if (isScrollingStart)
    {
        isScrollingStart=NO;
        isScrollingEnd=YES;
        [self scrollingStopped];
    }
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    isScrollingStart=YES;
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    isScrollingStart=YES;
}
-(void)scrollingStopped
{
    NSMutableArray* arrVideoCells=[NSMutableArray array];
    NSLog(@"Scrolling stopped");
    NSArray* arrVisibleCells=[self.tableTimeline visibleCells];
    for (TimeLineCell* cell in arrVisibleCells)
    {
        if ([cell isKindOfClass:[TimeLineCellMediaVideo class]])
        {
            [arrVideoCells addObject:cell];
        }
    }

    TimeLineCellMediaVideo* videoCell=[self getCellNearCenterOfScreen:arrVideoCells];

}
-(TimeLineCellMediaVideo*)getCellNearCenterOfScreen:(NSMutableArray*)arrCells
{
    TimeLineCellMediaVideo* closetCellToCenter;
    CGRect filterCGRect;
    for (TimeLineCellMediaVideo* videoCell in arrCells)
    {
        if (arrCells.count==1)
            closetCellToCenter= videoCell;


        NSIndexPath* cellIndexPath=[self.tableTimeline indexPathForCell:videoCell];
        CGRect rect = [self.tableTimeline convertRect:[self.tableTimeline rectForRowAtIndexPath:cellIndexPath] toView:[self.tableTimeline superview]];
        if (closetCellToCenter)
        {

            CGRect intersect = CGRectIntersection(self.tableTimeline.frame, filterCGRect);
            float visibleHeightFilterCell = CGRectGetHeight(intersect);

            intersect = CGRectIntersection(self.tableTimeline.frame, rect);
            float visibleHeightCurrentCell = CGRectGetHeight(intersect);
            if (visibleHeightCurrentCell>visibleHeightFilterCell)
            {
                filterCGRect=rect;
                closetCellToCenter= videoCell;
            }

        }
        else
        {
            closetCellToCenter=videoCell;
            filterCGRect=rect;

        }
    }
    return closetCellToCenter;
}

答案 5 :(得分:0)

我做了以下操作来找到大多数可见单元格的indexPath,并且它正常工作。

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            guard let tableView = scrollView as? UITableView else {
                return
            }
            let visibleHeights = tableView.visibleCells.compactMap { cell -> (indexPath: IndexPath, visibleHeight: CGFloat)? in
                guard let indexPath = tableView.indexPath(for: cell) else {
                    return nil
                }
                let cellRect = tableView.rectForRow(at: indexPath)
                let superView = tableView.superview
                let convertedRect = tableView.convert(cellRect, to: superView)
                let intersection = tableView.frame.intersection(convertedRect)
                let visibleHeight = intersection.height
                return (indexPath, visibleHeight)
            }

            guard let maxVisibleIndexPath = visibleHeights.max(by: { $0.visibleHeight < $1.visibleHeight })?.indexPath else {
                return
            }
            print("maxVisibleIndexPath: \(maxVisibleIndexPath)")

        }