【问题标题】:IOS Issue Getting Index Path Row at Specific PointIOS问题在特定点获取索引路径行
【发布时间】:2013-06-04 11:28:03
【问题描述】:

我有一个包含导航栏、表格视图和工具栏的视图控制器。我将 UITableViewDelegate 包含在视图控制器中,并通过情节提要正确地将表的数据源和委托分配给视图控制器。表格视图从远程数据库加载其数据,一旦表格滚动到最后一个单元格,就会将更多数据加载到表格中。我通过使用以下帖子中概述的 scrollViewDidScroll 和 indexPathForRowAtPoint 方法实现了这一点:How to know when UITableView did scroll to bottom in iPhone。但是,当我运行应用程序并滚动表时,indexPathForRowAtPoint 返回的唯一索引路径是表加载时位于指定点的索引路径。这是我滚动时得到的代码和输出:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGPoint bottomPoint = CGPointMake(160, 430);
    CGPoint topPoint = CGPointMake(160, 10);

    NSLog(@"%d", [[_tableView indexPathForRowAtPoint:bottomPoint] row]);

}

每次滚动都会输出以下内容:

2013-06-08 00:56:45.006 Coffee[24493:907] 3
2013-06-08 00:56:45.012 Coffee[24493:907] 3
2013-06-08 00:56:45.040 Coffee[24493:907] 3
2013-06-08 00:56:45.069 Coffee[24493:907] 3
2013-06-08 00:56:45.088 Coffee[24493:907] 3
2013-06-08 00:56:45.105 Coffee[24493:907] 3
2013-06-08 00:56:45.135 Coffee[24493:907] 3
2013-06-08 00:56:45.144 Coffee[24493:907] 3
2013-06-08 00:56:45.173 Coffee[24493:907] 3
2013-06-08 00:56:45.180 Coffee[24493:907] 3

其中 3 是控制器加载时底部点所在单元格的 indexPath.row。我做错了什么,为什么会这样?这与 UITableView 位于父视图控制器内的事实有什么关系吗?

【问题讨论】:

    标签: iphone ios uitableview


    【解决方案1】:
    let bottomPoint = CGPoint(x: tableView.frame.midX, y: tableView.frame.maxY)
    let converted = tableView.convert(point, from: tableView.superview)
    let indexPathForBottomCell = tableView.indexPathForItem(at: converted)
    

    这也应该有效,并且可能更容易理解。对于每种情况,所有额外的空格(如底部插图)都会有不同的处理方式。

    【讨论】:

      【解决方案2】:

      这是实现该功能的类。

      导入 UIKit

      类 ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

      @IBOutlet weak var tableView: UITableView!
      
      override func viewDidLoad() {
          super.viewDidLoad()
      
          let flagView = UIView(frame: CGRect(x: 0, y: 100.0, width: self.view.frame.width, height: 20.0))
      
              flagView.backgroundColor = .blue
      
              self.view.addSubview(flagView)
      
          // Do any additional setup after loading the view, typically from a nib.
      }
      
      override func didReceiveMemoryWarning() {
          super.didReceiveMemoryWarning()
          // Dispose of any resources that can be recreated.
      }
      
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          return 20
      }
      
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = UITableViewCell()
          cell.textLabel?.text = "Cell number: \(indexPath.row)"
          return cell
      }
      
      func scrollViewDidScroll(_ scrollView: UIScrollView) {
          if scrollView.contentOffset.y > 0 {
              let currentPoint = CGPoint(x: self.view.frame.width - 100, y: 100.0 + scrollView.contentOffset.y)
              print(" current index:  \(String(describing: tableView.indexPathForRow(at: currentPoint)?.row))")
          }
      }
      

      }

      【讨论】:

        【解决方案3】:

        正如您从 Apple 的文档中看到的,方法 indexPathForRowAtPoint: 是指接收器的本地坐标系中的一个点(表格视图的边界),但不是 表格视图的框架。由于您设置的bottomPoint 在表格视图的框架坐标系中,因此您不会得到正确的indexPath。 HalR 的回答给出了 table view 的边界坐标系中的 bottomPoint。

        indexPathForRowAtPoint:

        返回标识给定点的行和节的索引路径。

        - (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
        

        参数
        点: 接收器本地坐标系中的一个点(表格视图的边界)。

        返回值
        索引路径表示与点关联的行和部分,如果该点超出任何行的范围,则为nil

        仅供参考different between Frame and Bounds

        【讨论】:

          【解决方案4】:

          bottomPoint 正在您的scrollView 内寻找位置。您的 scrollView 包含一个表格,并且所有单元格始终位于同一位置,相对于您的 scrollView。这就是为什么你总是在那个时候得到同一个单元格。

          滚动时,scrollView 中的单元格不会移动,scrollView 相对于其父级“移动”。这是通过更改其 contentOffset 来完成的。

          如果您将 scrollView 的 y 内容偏移量添加到您的 bottomPoint,您将在您的 scrollView 中找到您可能真正要寻找的点。

          像这样:

          - (void)scrollViewDidScroll:(UIScrollView *)scrollView
          {
              CGPoint bottomPoint = CGPointMake(160, 430) - scrollView.contentOffset.y;
              CGPoint topPoint = CGPointMake(160, 10);
          
              NSLog(@"%d", [[_tableView indexPathForRowAtPoint:bottomPoint] row]);
          
          }
          

          【讨论】:

          • 感谢完美!没想到IOS就是这么干的。 @HalR
          • 当我开始使用 iOS 时,我一直在努力解决它。很高兴能帮到你。
          猜你喜欢
          • 2013-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-12
          相关资源
          最近更新 更多