我有一个视图控制器,其中包含导航栏,表格视图和工具栏。我在视图控制器中包含了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位于父视图控制器内的事实有关?
答案 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
。
答案 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)
这也应该起作用,并且可能更容易理解。对于每种情况,所有其他空格(例如底部插图)的处理方式都会不同。