【问题标题】:How to tell how much of a UITableViewCell is visible如何判断 UITableViewCell 有多少可见
【发布时间】:2012-02-22 04:01:39
【问题描述】:

UITableView 具有确定哪些单元格当前可见的方法。我想知道的是有多少细胞是可见的。

例如,当您将表格向下拖动时,表格顶部的“新可见”单元格不仅会出现,而且会一次显示一条(像素)行,直到整个单元格可见。在拖动表格视图时,我如何知道在任何给定时刻该单元格有多少可见。

我的最终目标是,当用户在表格上拖动时,根据在任何给定时间可见的数量来更改单元格内的显示视图。

有什么建议吗?

【问题讨论】:

    标签: ios uitableview


    【解决方案1】:

    这是上面在 Swift 中实现的变体:

        var cellRect = tableView.rectForRowAtIndexPath(indexPath)
        if let superview = tableView.superview {
            let convertedRect = tableView.convertRect(cellRect, toView:superview)
            let intersect = CGRectIntersection(tableView.frame, convertedRect)
            let visibleHeight = CGRectGetHeight(intersect)
        }
    

    visibleHeight 是单元格中可见的部分。可以添加进一步的步骤来计算可见单元格的比率 - 零和一之间:

        var cellRect = tableView.rectForRowAtIndexPath(indexPath)
        if let superview = tableView.superview {
            let convertedRect = tableView.convertRect(cellRect, toView:superview)
            let intersect = CGRectIntersection(tableView.frame, convertedRect)
            let visibleHeight = CGRectGetHeight(intersect)
            let cellHeight = CGRectGetHeight(cellRect)
            let ratio = visibleHeight / cellHeight
        }
    

    要根据可见性更改视图外观 - 如上述问题所述 - 此代码应包含在表视图的 UIScrollView 超类委托、UIScrollViewDelegate 方法 scrollViewDidScroll 中。

    但是,这只会影响滚动的单元格。已经可见的单元格不会受到影响。对于那些,应该在UITableViewDelegate方法didEndDisplayingCell中应用相同的代码。

    【讨论】:

      【解决方案2】:

      你可以试试这样的:

      -(void)scrollViewDidScroll:(UIScrollView *)sender
      {
          [self checkWhichVideoToEnable];
      }
      
      -(void)checkWhichVideoToEnable
      {
          for(UITableViewCell *cell in [tblMessages visibleCells])
          {
              if([cell isKindOfClass:[VideoMessageCell class]])
              {
                  NSIndexPath *indexPath = [tblMessages indexPathForCell:cell];
                  CGRect cellRect = [tblMessages rectForRowAtIndexPath:indexPath];
                  UIView *superview = tblMessages.superview;
      
                  CGRect convertedRect=[tblMessages convertRect:cellRect toView:superview];
                  CGRect intersect = CGRectIntersection(tblMessages.frame, convertedRect);
                  float visibleHeight = CGRectGetHeight(intersect);
      
                  if(visibleHeight>VIDEO_CELL_SIZE*0.6) // only if 60% of the cell is visible
                  {
                      // unmute the video if we can see at least half of the cell
                      [((VideoMessageCell*)cell) muteVideo:!btnMuteVideos.selected];
                  }
                  else
                  {
                      // mute the other video cells that are not visible
                      [((VideoMessageCell*)cell) muteVideo:YES];
                  }
              }
          }
      }
      

      【讨论】:

      • 谢谢哥们,我还没想过用CGRectIntersection,现在这么明显了!
      【解决方案3】:

      我还没有测试过,但我会尝试以下方式:

      UITableViewCell *cell;
      UIView *parent = cell.superview;
      CGRect overlap = CGRectIntersection(cell.frame, parent.bounds);
      

      然后比较特定的矩形。

      【讨论】:

        【解决方案4】:

        在这里查看 Vadim Yelagin 的回答:https://stackoverflow.com/a/9843146/758298,它解释了如何将单元格矩形转换为父表视图坐标并确定它是否完全可见。

        【讨论】:

          【解决方案5】:

          我使用 bshirley 的建议和其他一些建议来制作这样的东西。就像我的东西的魅力一样,一次只显示几个单元格。如果您想将其与更多单元格一起使用,可能需要进行一些调整

              - (void) scrollViewDidEndDecelerating:(UITableView *)scrollView {
          
          NSArray *visibleCellIndexPaths = TableView.indexPathsForVisibleRows;
          NSIndexPath *indexPathLow = [visibleCellIndexPaths valueForKeyPath:@"@min.self"];
          NSIndexPath *indexPathHigh = [visibleCellIndexPaths valueForKeyPath:@"@max.self"];
          
          NSArray *cells = TableView.visibleCells;
          
          UITableViewCell *cell1 = [cells objectAtIndex:0];
          UIView *parent1 = cell1.superview;
          CGRect overlap1 = CGRectIntersection(cell1.frame, parent1.bounds);
          
          UITableViewCell *cell2 = [cells objectAtIndex:1];
          UIView *parent2 = cell2.superview;
          CGRect overlap2 = CGRectIntersection(cell2.frame, parent2.bounds);
          
          if (overlap1.size.height > overlap2.size.height) {
              [TableView scrollToRowAtIndexPath:indexPathLow atScrollPosition:UITableViewScrollPositionTop animated:YES];
          } else {
              [TableView scrollToRowAtIndexPath:indexPathHigh atScrollPosition:UITableViewScrollPositionTop animated:YES];
          }
          

          }

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-12-09
            • 2016-07-29
            • 2011-02-16
            • 2014-05-03
            • 1970-01-01
            • 1970-01-01
            • 2011-09-10
            • 1970-01-01
            相关资源
            最近更新 更多