IOS问题在特定点获取索引路径行

时间:2013-06-08 05:01:03

标签: iphone ios uitableview

我有一个视图控制器,其中包含导航栏,表格视图和工具栏。我在视图控制器中包含了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位于父视图控制器内的事实有关?

4 个答案:

答案 0 :(得分:9)

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

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

如果您将scrollView的内容偏移量添加到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]);

}

答案 1 :(得分:3)

从Apple的文档中可以看出,方法indexPathForRowAtPoint:是指接收器的本地坐标系中的一个点(表视图的边界), BUT否表格视图的框架。由于您设置的bottomPoint位于表格视图的框架坐标系中,因此您将无法获得正确的indexPath。 HalR的答案给出了表视图边界坐标系中的bottomPoint。

indexPathForRowAtPoint:

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

- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point

<强>参数
点:   接收器的局部坐标系中的一个点(表视图的边界)。

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

仅供参考different between Frame and Bounds

答案 2 :(得分:1)

这是实现该功能的类。

导入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 :(得分:0)

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)

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