57

我已经阅读了苹果文档,对于Objective-C像我这样的初学者来说,这是无法理解的。我正在尝试UITableView按照此 链接示例实现多列,但它不起作用,所以我需要理解如何cellForRowAtIndexPath工作,因为对我个人而言,这种方法似乎相当复杂。

1)它返回什么?UITableViewCell? 但为什么看起来如此奇怪?

-(UITableViewCell *)tableView:(UITableView *)tableView 
  • 那是什么?你能解释一下吗?

2)它是如何被调用的,更重要的是我如何将它连接到某个UITableView??? 如果我有两个UITableView命名firstTableView并且secondTableView我希望它们不同(以cellForRowAtIndexPath不同方式执行)怎么办?我应该如何将我的链接UITableViews到这个

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

该方法接受NSIndexPath,不是UITableView。我要做什么?

4

3 回答 3

96

我会尝试分解它(来自文档的示例)

/* 
 *   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 方法中指定)在屏幕上显示单元格时调用它。

于 2011-11-10T12:49:45.520 回答
38

1)该函数返回一个表格视图的单元格是吗?所以,返回的对象是 type UITableViewCell。这些是您在表格行中看到的对象。这个函数基本上返回一个单元格,用于表格视图。但是您可能会问,函数如何知道要为哪一行返回哪个单元格,这在第二个问题中得到了回答

2)NSIndexPath本质上是两件事-

  • 你的部分
  • 你的行

因为您的表格可能被分成许多部分,并且每个部分都有自己的行,所以这NSIndexPath将帮助您准确识别哪个部分和哪一行。它们都是整数。如果您是初学者,我会说只尝试一个部分。

如果您UITableViewDataSource在视图控制器中实现该协议,则会调用它。更简单的方法是添加一个UITableViewController类。我强烈推荐这个,因为 Apple 为您编写了一些代码来轻松实现可以描述表格的函数。无论如何,如果您选择自己实现此协议,则需要创建一个UITableViewCell对象并将其返回给任何行。查看其类参考以了解可重用性,因为在表格视图中显示的单元格被一次又一次地重用(顺便说一句,这是一个非常有效的设计)。

至于当你有两个表视图时,看方法。表格视图已传递给它,因此您对此应该没有问题。

于 2011-11-10T12:50:15.030 回答
6

基本上它是在设计你的单元格,每个单元格都会调用 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
}
于 2015-05-08T09:58:39.310 回答