【问题标题】:Multiple UITableViewCells different fields per row每行有多个 UITableViewCells 不同的字段
【发布时间】:2014-01-20 15:14:27
【问题描述】:

我有 2 个表视图,第一个仅从数组加载列表。 另一个 1,显示每行的详细信息。但它显示了一个崩溃报告:

'UITableView dataSource 必须从 tableView 返回一个单元格:cellForRowAtIndexPath: Exception'

我的代码似乎有什么问题?我想向每一行显示来自同一 sqlite 行的不同细节。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     UITableViewCell *cell;
     //tableView 1  
     if(tableView == self.cTableLabel)
     {
          cell = [tableView dequeueReusableCellWithIdentifier:@"courseCell"];
          NSLog(@"Here.");
          Course *courses = [self.course objectAtIndex:indexPath.row];
          cell.textLabel.text =courses.cName;
          cell.detailTextLabel.text =courses.cSchool;
          return cell;
     }
     //tableView 2
     if(tableView == self.jTableLabel)
     {
          if (indexPath.row == 0)
          {
               cell = [tableView dequeueReusableCellWithIdentifier:@"JobName"];
               cell.textLabel.text = _jDetails.jName;
          }
          else if (indexPath.row == 1)
          {
               cell=  [tableView dequeueReusableCellWithIdentifier:@"JobEarnings"];
               cell.textLabel.text  = @"Job Earnings (per month): Php";
               cell.detailTextLabel.text = _jDetails.jEarnings;
          }
          return cell;
     }
     return 0;

}

【问题讨论】:

    标签: ios objective-c uitableview


    【解决方案1】:

    出于性能原因,当表格视图的数据源在其tableView:cellForRowAtIndexPath: 方法中将单元格分配给行时,通常应该重用 UITableViewCell 对象。表视图维护数据源已标记为重用的 UITableViewCell 对象的队列或列表。当被要求为表格视图提供新单元格时,从您的数据源对象调用此方法。如果一个现有单元可用,则此方法使现有单元出列,或者使用您之前注册的类或 nib 文件创建一个新单元。如果没有单元格可重用并且您没有注册类或 nib 文件,则此方法返回 nil。

    如果您为指定的标识符注册了一个类并且必须创建一个新单元格,则此方法通过调用其initWithStyle:reuseIdentifier: 方法来初始化该单元格。对于基于 nib 的单元格,此方法从提供的 nib 文件加载单元格对象。如果现有单元格可供重用,则此方法将调用该单元格的 prepareForReuse 方法。

    【讨论】:

      【解决方案2】:

      你需要为每个tableview创建不同的cell,尝试使用上面的代码:

       -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
             static NSString *CellIdentifier = @"Cell";
              UITableViewCell *cell;
               //tableView 1  
               if(tableView == self.cTableLabel)
               {
           cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
              if (cell == nil)
              {
                  cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
              }
              else
              {
                  for(UIView *view in cell.contentView.subviews)
                  {
                      [view removeFromSuperview];
                  }
              }
                    NSLog(@"Here.");
                    Course *courses = [self.course objectAtIndex:indexPath.row];
                    cell.textLabel.text =courses.cName;
                    cell.detailTextLabel.text =courses.cSchool;
                    return cell;
               }
               //tableView 2
               if(tableView == self.jTableLabel)
               {
              cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
              if (cell == nil)
              {
                  cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
              }
              else
              {
                  for(UIView *view in cell.contentView.subviews)
                  {
                      [view removeFromSuperview];
                  }
              }
                    if (indexPath.row == 0)
                    {
                         cell = [tableView dequeueReusableCellWithIdentifier:@"JobName"];
                         cell.textLabel.text = _jDetails.jName;
                    }
                    else if (indexPath.row == 1)
                    {
                         cell=  [tableView dequeueReusableCellWithIdentifier:@"JobEarnings"];
                         cell.textLabel.text  = @"Job Earnings (per month): Php";
                         cell.detailTextLabel.text = _jDetails.jEarnings;
                    }
                    return cell;
               }
               return 0;
      
          }
      

      【讨论】:

        【解决方案3】:

        请交叉检查您的任一表是否在 numberOfRowsInSection 方法中返回更多行数。可能是您没有检查此方法,因为两个表都返回了不同的行数。

        【讨论】:

          【解决方案4】:

          首先,检查您的numberOfRowsInSection 是否为您的表返回正确的行数。我想就是这样。

          -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
              if(tableView == self.cTableLabel)
              {
                  return [self.course count];
          
              }
              //tableView 2
              if(tableView == self.jTableLabel)
              {
                  return 2;
              }
          
              return 0;
          }
          

          否则我会在return 0; 或 NSLog 之前在cellForRowAtIndexPath 中设置一个断点,因为我的猜测是,如果块被击中并且您返回零。会触发吗?

          编辑 - 啊,我想我看到 dequeueReusableCellWithIdentifier: 如果您还没有设置一个单元格,它将返回一个 nil 单元格。尝试改用dequeueReusableCellWithIdentifier: forIndexPath:。假设您首先调用了registerClass:[UITableViewCell class] forCellReuseIdentifier:,这将始终返回一个有效的单元格。

          试一试:

          -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
              UITableViewCell *cell;
              [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"courseCell"];
              [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"JobName"];
              [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"JobEarnings"];
          
              //tableView 1
              if(tableView == self.cTableLabel)
              {
                  cell = [tableView dequeueReusableCellWithIdentifier:@"courseCell" forIndexPath:indexPath];
                  NSLog(@"Here.");
                  Course *courses = [self.course objectAtIndex:indexPath.row];
                  cell.textLabel.text =courses.cName;
                  cell.detailTextLabel.text =courses.cSchool;
                  return cell;
              }
              //tableView 2
              if(tableView == self.jTableLabel)
              {
                  if (indexPath.row == 0)
                  {
                      cell = [tableView dequeueReusableCellWithIdentifier:@"JobName" forIndexPath:indexPath];
                      cell.textLabel.text = _jDetails.jName;
                  }
                  else if (indexPath.row == 1)
                  {
                      cell=  [tableView dequeueReusableCellWithIdentifier:@"JobEarnings" forIndexPath:indexPath];
                      cell.textLabel.text  = @"Job Earnings (per month): Php";
                      cell.detailTextLabel.text = _jDetails.jEarnings;
                  }
                  return cell;
              }
              return 0;
          
          }
          

          registerClass:[UITableViewCell class] forCellReuseIdentifier: 也可以在你的 init 中调用,它只需要声明一次。

          【讨论】:

          • 嗯.. 那么它命中了哪个返回语句?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-25
          • 2018-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多