获取 UITableViewCell 的确切位置
Posted
技术标签:
【中文标题】获取 UITableViewCell 的确切位置【英文标题】:Getting the exact location of a UITableViewCell 【发布时间】:2011-06-08 14:23:04 【问题描述】:给定UITableView
,如何找到特定UITableViewCell
的位置?换句话说,我希望它的框架相对于我的 iPhone 屏幕,而不是相对于UITableView
。所以如果我的UITableView
向上滚动,每个UITableViewCell
的位置在屏幕上应该更高,等等。
【问题讨论】:
【参考方案1】:您还可以使用rectForRowAtIndexPath
方法通过发送indexPath 来获取UITableView
的位置。
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath
所以使用如下:
CGRect myRect = [tableView rectForRowAtIndexPath:indexPath];
【讨论】:
你在哪个函数中访问rectForRowAtIndexPath
方法?
在 didSelectRow... 方法中
@reising1: 一定不能崩溃,如果还是有同样的问题可以显示相关代码。【参考方案2】:
除了 rectForRowAtIndexPath 你还需要考虑滚动。
试试这个代码:
// Get the cell rect and adjust it to consider scroll offset
CGRect cellRect = [tableView rectForRowAtIndexPath:indexPath];
cellRect = CGRectOffset(cellRect, -tableView.contentOffset.x, -tableView.contentOffset.y);
【讨论】:
这会产生单元格的屏幕坐标,+1 ! +1 用于考虑内容偏移。这会将单元格映射到其屏幕坐标。很好,谢谢。 第二行可以简单点:cellRect = CGRectOffset(cellRect, -tableView.contentOffset.x, -tableView.contentOffset.y);
如果您有任何(-tableView.contentOffset.y-tableView.contentInset.top)
,您可能还想减去 tableview 的 contentInsets
rectForRowAtIndex
将返回 UITableView 坐标系中的矩形。使用这里描述的convertRect
方法***.com/questions/687793/… 将其转换为超级视图的坐标系,而不是手动摆弄偏移和插入。【参考方案3】:
尝试以下操作(将 nil 作为 toView 参数发送意味着您要将矩形转换为窗口坐标):
CGRect r = [cell convertRect:cell.frame toView:nil];
请记住,如果特定行当前不可见,则可能没有 UITableViewCell 用于它 - 因此在使用该代码之前,您可能需要检查单元格是否有效(例如不是 nil)
【讨论】:
这会引发错误。程序终止。是的,单元格是可见的。 错误信息是什么?以及如何获取单元格对象?【参考方案4】:斯威夫特 3
相对于tableView
:
let rect = self.tableView.rectForRow(at: indexPath)
相对于Screen
:
如果你只知道cell
,
if let indexPath = tableView.indexPath(for: cell)
let rect = self.tableView.rectForRow(at: indexPath)
let rectInScreen = self.tableView.convert(rect, to: tableView.superview)
如果您知道indexPath
,则无需调用if
语句。
【讨论】:
【参考方案5】:试试看 在
didSelectRowAtIndexPath
方法
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// get current location of selected cell
CGRect rectInTableView = [tableView rectForRowAtIndexPath:indexPath];
CGRect rectInSuperview = [tableView convertRect:rectInTableView toView:[tableView superview]];
NSLog(@"Cell Y Is %f",rectInSuperview.origin.y);
NSLog(@"Cell X Is %f",rectInSuperview.origin.x);
【讨论】:
【参考方案6】:Jhaliya 的回答对我来说还不够,我需要做更多的操作才能让它发挥作用。我的 tableView 被添加到 viewController 并且它的位置在屏幕的右半部分。因此,您需要将 tableView 原点作为滚动偏移量考虑在内。
CGRect rowRect = [tableView rectForRowAtIndexPath:indexPath];
CGPoint offsetPoint = [self.infoTableView contentOffset];
// remove the offset from the rowRect
rowRect.origin.y -= offsetPoint.y;
// Move to the actual position of the tableView
rowRect.origin.x += self.infoTableView.frame.origin.x;
rowRect.origin.y += self.infoTableView.frame.origin.y;
【讨论】:
【参考方案7】:对于未来的观众,我无法为 UITableView
中的单元格获取可靠的框架。我试图在需要弹出框演示的 iPad 上以 ActionSheet 样式显示UIAlertController
。最后,这种方法产生了最好的结果:
// 44 is the standard height for a cell in a UITableView
// path is the index path of the relevant row
// controller is the UIAlertController
CGRect frame = CGRectZero;
frame.origin.y = 44 * path.row;
frame.origin.x = table.frame.origin.x;
frame.size = CGSizeMake(table.frame.size.width, 44);
controller.popoverPresentationController.sourceRect = [tableView convertRect:frame toView:self.view];
controller.popoverPresentationController.sourceView = self.view;
【讨论】:
我最终使用了您的答案。与其硬编码为 44,不如使用 cellForRowAtIndexPath,然后使用单元格的 bounds.height。【参考方案8】:Tomasz 和 Jhaliya 的 Swift 版本的答案,以防任何人(其他人)对此感到困惑:
var cellRect = tableView.rectForRow(at: indexPath)
cellRect = cellRect.offsetBy(dx: -tableView.contentOffset.x, dy: -tableView.contentOffset.y)
【讨论】:
【参考方案9】:如果您确实需要专门转换为窗口中的某个点,您可以这样做:
[yourAppDelegate.window convertPoint:[cell.contentView.center] fromView:[cell.contentView]];
我使用了单元格中心坐标,但你可以使用任何你想要的点。
Vladimir 是对的,请注意不可见的行(或已被回收的行)。
-S
【讨论】:
以上是关于获取 UITableViewCell 的确切位置的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UITableViewCell 中获取 UIImageview 的屏幕位置