cellForRowAtIndexPath 是如何工作的?
Posted
技术标签:
【中文标题】cellForRowAtIndexPath 是如何工作的?【英文标题】:How does cellForRowAtIndexPath work? 【发布时间】:2011-12-26 03:21:50 【问题描述】:我已经阅读了苹果文档,对于像我这样Objective-C
的初学者来说,这是无法理解的。我正在尝试按照这个link 示例实现多列UITableView
,但它不起作用,所以我需要了解cellForRowAtIndexPath
的工作原理,因为对我个人而言,这种方法似乎相当复杂。
1) 它返回什么? UITableViewCell
?但为什么看起来如此奇怪?
-(UITableViewCell *)tableView:(UITableView *)tableView
那是什么?你能解释一下吗?
2)它是如何被调用的,更重要的是我如何将它连接到某个UITableView
???如果我有两个名为firstTableView
和secondTableView
的UITableView
并且我希望它们不同(以不同方式执行cellForRowAtIndexPath
)怎么办?我应该如何将我的UITableViews
链接到这个
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
该方法接受NSIndexPath
,而不是UITableView
。我该怎么办?
【问题讨论】:
刚回答这个问题。我知道这是 6 岁,但无论如何......实例方法被描述为:- (return_type)firstPartOfMethodName:(first_param_type)first_param secondPartOfMethodName:(second_param_type)second_param ...
,其中return_type
是该方法返回的值的类型,first_param_type
、second_param_type
等是传递给方法的参数类型,first_param
、second_param
等是传递给方法的实际变量,firstPartOfMethodName:secondPartOfMethodName:...
是方法的名称(或签名)。
【参考方案1】:
我会尝试分解它(来自documention 的示例)
/*
* The cellForRowAtIndexPath takes for argument the tableView (so if the same object
* is delegate for several tableViews it can identify which one is asking for a cell),
* and an indexPath which determines which row and section the cell is returned for.
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
/*
* This is an important bit, it asks the table view if it has any available cells
* already created which it is not using (if they are offScreen), so that it can
* reuse them (saving the time of alloc/init/load from xib a new cell ).
* The identifier is there to differentiate between different types of cells
* (you can display different types of cells in the same table view)
*/
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
/*
* If the cell is nil it means no cell was available for reuse and that we should
* create a new one.
*/
if (cell == nil)
/*
* Actually create a new cell (with an identifier so that it can be dequeued).
*/
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
/*
* Now that we have a cell we can configure it to display the data corresponding to
* this row/section
*/
NSDictionary *item = (NSDictionary *)[self.content objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:@"mainTitleKey"];
cell.detailTextLabel.text = [item objectForKey:@"secondaryTitleKey"];
NSString *path = [[NSBundle mainBundle] pathForResource:[item objectForKey:@"imageKey"] ofType:@"png"];
UIImage *theImage = [UIImage imageWithContentsOfFile:path];
cell.imageView.image = theImage;
/* Now that the cell is configured we return it to the table view so that it can display it */
return cell;
这是一个DataSource
方法,因此它将在任何将自己声明为DataSource
的UITableView
的对象上调用。当表格视图实际需要根据行数和节数(您在其他 DataSource 方法中指定)在屏幕上显示单元格时调用它。
【讨论】:
由于这个线程提供了很多信息,我想添加一点可能也有帮助的信息。如果您从代码的某些部分启动重新加载,也会调用此方法。例如- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation 你不应该把cell.selectionStyle = UITableViewCellSelectionStyleNone;
放在if 块之外吗?当我放入其中时,它不起作用。【参考方案2】:
1) 该函数返回一个表格视图的单元格是吗?因此,返回的对象是UITableViewCell
类型。这些是您在表格行中看到的对象。这个函数基本上返回一个单元格,用于表格视图。
但是你可能会问,函数如何知道要为哪一行返回哪个单元格,这在第二个问题中得到了回答
2)NSIndexPath
本质上是两件事-
因为您的表格可能分为许多部分,并且每个部分都有自己的行,所以这个NSIndexPath
将帮助您准确识别哪个部分和哪一行。它们都是整数。如果您是初学者,我会说只尝试一个部分。
如果您在视图控制器中实现UITableViewDataSource
协议,则会调用它。一种更简单的方法是添加一个UITableViewController
类。我强烈推荐这个,因为 Apple 为您编写了一些代码来轻松实现可以描述表格的函数。无论如何,如果您选择自己实现此协议,则需要创建一个UITableViewCell
对象并将其返回给任何行。查看它的类参考以了解可重用性,因为表格视图中显示的单元格被一次又一次地重用(顺便说一句,这是一个非常有效的设计)。
至于当你有两个表视图时,看方法。表格视图已传递给它,因此您对此应该没有问题。
【讨论】:
【参考方案3】:基本上它是在设计你的单元格,每个单元格都会调用 cellforrowatindexpath ,单元格编号由 indexpath.row 找到,节号由 indexpath.section 找到。在这里,您可以使用任何您想要的标签、按钮或文本图像,它们会针对表中的所有行进行更新。 回答第二个问题 在索引路径的行的单元格中使用 if 语句
在目标 C 中
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(tableView == firstTableView)
//code for first table view
[cell.contentView addSubview: someView];
if(tableview == secondTableView)
//code for secondTableView
[cell.contentView addSubview: someView];
return cell;
在 Swift 3.0 中
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
if(tableView == firstTableView)
//code for first table view
if(tableview == secondTableView)
//code for secondTableView
return cell
【讨论】:
你应该使用静态的 NSString *CellIdentifier = @"CellIdentifier";这个委托是动态的,所以任何静态的都必须正确声明。 但是字符串并没有改变,每次加载单元格时它始终是“CellIdentifier”,而不是其他内容,因此单元格被重用,如果我错了,请纠正我。 字符串没有变化,是的。但由于委托被多次调用,它将被创建多次。使用 static 确保字符串被创建一次并被重用。以上是关于cellForRowAtIndexPath 是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
tableView(cellForRowAtIndexPath) 与 tableView.cellForRowAtIndexPath()?
如何交替调用 numberOfRowsInSection 和 cellForRowAtIndexPath
如何将动态行和节数组传递给 numberOfRowsInSection 和 cellForRowAtIndexPath
如何从 cellForRowAtIndexPath 获取 textField 上的边框线?
如何在 cellforrowatindexpath 之后更新自定义表格单元格中的 UIButton 图像?
NSFetchedResultsController - 如何在 cellForRowAtIndexPath 中显示正确的部分行