UITableViewCell 怎么知道自己的 indexPath?
Posted
技术标签:
【中文标题】UITableViewCell 怎么知道自己的 indexPath?【英文标题】:How can a UITableViewCell know of its own indexPath? 【发布时间】:2009-07-28 15:23:51 【问题描述】:标准的 Grouped UITableView
样式允许在每个部分的顶部和底部使用圆角绘制 UITableViewCell
s。这是如何实现的?单元格如何知道自己在其部分中的位置,以及它如何知道何时更改其圆角?
我想制作自己的圆形单元格,我有图片要使用,但不知道什么时候显示哪个图片
注意:我已经知道 UITableView 是如何工作的,并且我知道如何使用它。我只是想,既然 UITableView 能够在正确的位置自动绘制圆角,我应该也可以,而无需向我的数据源或委托添加任何内容。
【问题讨论】:
【参考方案1】:NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
int rows = [(UITableView *)self.superview numberOfRowsInSection:indexPath.section];
if (indexPath.row == 0 && rows == 1)
// the one and only cell in the section
else if (indexPath.row == 0)
//top
else if (indexPath.row != rows - 1)
//middle
else
//bottom
【讨论】:
答案只有一半,但它如何在单元格移动时自动更改圆角? 你可以把这段代码放在你的cell子类的layoutSubviews中。 此解决方案将来可能不再适用。您无法预测您的 UITableViewCell 是它的 tableview 的直接子视图...【参考方案2】:这很简单。假设 cell 是对象,它的位置要被找出来。
UITableView* table = (UITableView *)[cell superview];
NSIndexPath* pathOfTheCell = [table indexPathForCell:cell];
NSInteger sectionOfTheCell = [pathOfTheCell section];
NSInteger rowOfTheCell = [pathOfTheCell row];
【讨论】:
这并不是特别有用,因为它不知道单元格何时更改自己的行或何时成为部分中的第一行或最后一行或唯一行。当这些事情发生时,我需要一种方法来获得回调。【参考方案3】:UITableViewCell
的 sectionLocation
方法返回整数,告诉你你需要什么:
自 2010 年以来,我在多个生产应用程序中使用它没有任何问题。
更新:我们的一个二进制文件最近(2018 年底)被自动拒绝,因为我们使用的是“sectionLocation”属性,所以它不再是一个好的选择。
在你的头文件中添加这样的东西,你就可以使用它了:
typedef NS_ENUM(NSInteger, MMMTableViewCellLocation)
MMMTableViewCellLocationUndefined = 0,
MMMTableViewCellLocationMiddle = 1,
MMMTableViewCellLocationTop = 2,
MMMTableViewCellLocationBottom = 3,
MMMTableViewCellLocationSingle = 4
;
@interface UITableViewCell ()
/** Undocumented method of UITableViewCell which allows to know where within section the cell is located,
* so the cell can draw its borders properly. */
- (MMMTableViewCellLocation)sectionLocation;
/** Override this one to know when the value of sectionLocation changes. */
- (void)setSectionLocation:(MMMTableViewCellLocation)sectionLocation animated:(BOOL)animated;
@end
【讨论】:
【参考方案4】:你可以使用
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell
对于这个问题。在我的示例中,我使用它来将单元格(带有自定义内容)滚动到视图的顶部。
【讨论】:
除了 UITableViewCell 没有对其表的引用。【参考方案5】:如果您需要更强大和更通用的东西,请查看 http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html - Matt Gallagher 非常有效地展示了您的需求。他基本上从 UIViewController 重新创建了 UITableViewController,同时增加了使用您自己的自定义图形的能力。我正在努力将它应用到我的一个项目中,到目前为止它看起来可以完成这项工作。
【讨论】:
【参考方案6】:不幸的是,我没有找到解决此问题的方法,因此我将 UITableViewController 和 UITableViewCell 子类化为一个通用的解决方案,我可以根据需要对其进行扩展。
【讨论】:
【参考方案7】:您不会在单元格中执行此操作。在 [tableView viewForHeaderInSection] 和 viewForFooterInSection 中绘制圆角。
我这样做的方式是使用Plain tableview样式,然后使用这两个视图进行圆度和单元格是正常的,没有圆形。
【讨论】:
您能详细说明一下吗?我不明白这将如何解决。 为了避免跟上第一行和最后一行的诡计,我使用了节页眉和页脚,并在其中绘制了圆形部分。这使行保持干净,具有简单的背景图像视图。您基本上需要仔细切割设计。如果您需要呈现行选择(选择边缘行时必须更改页眉或页脚),则它不适用,因此我将这种简单的技术用于不需要选择的东西。好处是它很容易实现,在默认的 UITableViewController 中。 这可能有效,但不是首选方式,因为稍后可能需要页眉和页脚。您可以通过询问 UITableView indexPathForCell:cell 来获取当前单元格 indexPath。如果为 0 且单元格数为 1,则在所有四个角上绘制圆角,否则如果 0 在顶部绘制圆角,否则如果 > 0 但不是单元格数 -1 在底部绘制圆角,否则不绘制圆角(中间细胞)。【参考方案8】:无需了解谁绘制了什么,您可以很容易地知道哪个单元格是 cellForRowAtIndexPath 内其部分中的最后一个单元格。
您已传入需要提供的单元格的 indexPath,对吗?您还通过了 tableView。
调用 [tableView numberofRowsInSection:indexPath.section],如果它是 == ([indexPath.row]-1),您知道您被要求提供该部分中的最后一个单元格。
在调用 cellForRowAtIndexPath 时,保证单元格在传入的 indexPath 处。
【讨论】:
是的,但是在移动行或删除行时不会调用 cellForRowAtIndexPath。【参考方案9】:为了扩展 Darren 的答案(我发现它最有用,谢谢 Darren!),您可以做的是遍历所有超级视图,直到找到父 UITableView。这应该是未来的证明,因为您不依赖于固定的视图层次结构。
我使用递归方法,如果找到 UITableView 则返回,如果没有则返回 nil。
- (UITableView *)parentTableViewOf:(UIView *)view
Class class = [view.superview class];
NSLog(@"Class : %@", NSStringFromClass(class));
if([view.superview isKindOfClass:[UITableView class]])
return (UITableView *)view.superview;
else
return [self parentTableViewOf:view.superview];
return nil;
到目前为止,我已经使用了这个,它似乎可以正常工作。希望能帮助到你! :)
【讨论】:
谢谢!我对其进行了修改以确保它在到达 UIWindow 时不会无限循环。 - (UITableView *)parentTableViewOf:(UIView *)view if ([view.superview isKindOfClass:[UITableView class]]) return (UITableView *)view.superview; else if (![view.superview isKindOfClass:[UIWindow class]]) return [self parentTableViewOf:view.superview]; 返回零; 【参考方案10】:单元格不知道他们去哪里...表格视图有单元格,您是告诉表格视图单元格中的内容的人。您在实现 cellForRowAtIndexPath 的 DataSource 中执行此操作...其工作方式:
一个索引路径有一行和一个节
对于分组表视图
一个部分属于一个组,一行属于该部分中的 1 个条目, UITableView 知道一个部分中有多少行以及有多少个部分的方式是 DataSources 方法 numberOfSectionInTableView 和方法 numberOfRowsInSection,这将正确调用 cellForRowAtIndexPath,由您来识别正在查询的部分和行您需要根据这些规范构建您的单元格。
一个很好的方法是你可以有一个字典,其中包含部分名称的键和 NSArray 的值以及该部分中的值。
所以你对 numberOfSectionsInRows 的实现看起来像
return [[dictionary allKeys] count]
numberOfRowsInSection 的实现看起来像
NSString* key=[[dictionary allKeys] objectAtIndex:sectionNumber]
return [[dictionary objectForKey:key] count]
您可以随时参考http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/TableView_iPhone/Introduction/Introduction.html 的 UITableView 编程指南 希望有帮助
【讨论】:
这不是一个特别有用的答案。我已经知道 UITableView 是如何工作的,并且我知道如何使用它。我只是想,既然 UITableView 能够在正确的位置自动绘制圆角,我应该也可以,而不需要向我的数据源或委托添加任何东西。 UITableView 没有绘制圆角,UITableCell 在其 draw 方法中看起来像那样...... 如果你想拥有自己的自定义单元子类 UITableViewCell 并在那里进行自定义,我猜你的问题不是特别清楚,对不起所有的 cmets 是的,我也知道。我的问题非常具体,因为我在 UITableViewCell 中进行自定义,我怎么知道要绘制哪些圆角? 哦,我明白了,因为不同的单元格有不同的角?好吧,我可以建议我将 indexPath 传递给单元格,并基于此知道该做什么。或者只是创建 UITableViewCell 的不同子类,当你返回它们时,根据 indexPath,制作合适的子类【参考方案11】:只需向自定义 UITableViewCell(取决于实现)类添加一个属性,该类包含一个 int、NSNumber 或 NSIndexPath,指定它是哪一个。如果您使用的是数据结构,然后将其放入该数据结构中的元素中。然后,您只需在创建数据结构时设置属性,例如 elt.id=i,然后在 cellForRowAtIndexPath 中访问它,例如 if (elt.id == 0 || elt.id == n-1 ) 其中 n 是您的部分中的行数。
我可能完全错过了你的问题,但如果我错过了,请发表评论,我会再次发布。
【讨论】:
是的,你有点错过了这个问题。我知道如何在创建时静态地告诉单元格它在哪里。但是,这并不能告诉它是否在其部分的底部而不告诉它它在哪个表中。即便如此,问题在于它是静态的。如果我删除第一行,我需要通知第二行自行重置。使用常规 UITableViewCells 时我不必这样做。 那么在这种情况下,您可以调用 reloadData,并且应该为剩余的单元格分别调用一次 cellForRowAtIndex 路径,此时您可以将矩形的第二个和第二个到最后一个单元格变成圆形的。以上是关于UITableViewCell 怎么知道自己的 indexPath?的主要内容,如果未能解决你的问题,请参考以下文章
自定义 UITableViewCell 中的按钮操作会影响其他单元格
带有在代码中绘制的自定义图像的 UITableViewCell
自定义 UITableViewCell 打开不同的 xib 子视图