【问题标题】:UITableView: `tableView:cellForRowAtIndexPath:` not called for all rowsUITableView: `tableView:cellForRowAtIndexPath:` 没有为所有行调用
【发布时间】:2011-06-28 02:41:32
【问题描述】:

我创建了一个包含 4 个部分和 3 行的 UITableView,总共 12 行。但是

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

上面的方法只被调用了 9 次而不是 12 次。为什么会这样? 我的第 4 部分没有构建,但我的第 1 部分被复制为第 4 部分。

请参考下面我的代码

@interface MainViewController : UITableViewController<UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource>
 {
}
@end


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad 
{
  CGRect frameRect = CGRectMake(0,0,320,460);

  UITableView *tableView = [[UITableView alloc] initWithFrame:frameRect   
  style:UITableViewStyleGrouped];
  tableView.delegate = self;
  tableView.dataSource = self;  
  tableView.backgroundColor = [UIColor purpleColor];
  tableView.scrollEnabled = YES;

  self.view = tableView;
  [tableView release];

  [super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return 3;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 4;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
     NSLog(@"CELL IS NIL %i", indexPath.section);

  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil)
  {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

      if (indexPath.section == 0)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"Tmail";

              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else if ( indexPath.row == 1 )
          {
              cell.text = @"English";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else
          {
              cell.text = @"Hindi";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
      }
      else if (indexPath.section == 1)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"Street";

              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else if ( indexPath.row == 1 )
          {
              cell.text = @"City";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else
          {
              cell.text = @"State";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
      }
      else if (indexPath.section == 2)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"Salem";

              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else if ( indexPath.row == 1 )
          {
              cell.text = @"Samalpatti";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else
          {
              cell.text = @"Chennai";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
      }

      else if (indexPath.section == 3)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"NOKIA";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else if ( indexPath.row == 1)
          {
              cell.text = @"SAMSUNG";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
          else
          {
              cell.text = @"SONY";
              UITextField *aField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];
              aField.placeholder = @"Mandatory";
              aField.delegate = self;
              aField.textColor = [UIColor blackColor];
              [cell addSubview:aField];
              [aField release];
          }
      }
   }

  return cell;
}

【问题讨论】:

  • 尝试干净的构建。并从项目文件夹中删除构建目录。我遇到了同样的问题,甚至更糟。所以也删除构建目录
  • @barbaghal,通过它显示的图像,您需要调整文本框和标签框,在它们之间留出空隙。

标签: ios iphone uitableview iphone-sdk-3.0


【解决方案1】:

实际上,当您滚动时,会创建其他行以防您有更多行,因此认为您需要像这样编写此代码,

编辑了一个

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
         NSLog(@"CELL IS NIL %i", indexPath.section);

      static NSString *CellIdentifier = @"Cell";
if (cell == nil) 
    {

        CGRect CellFrame = CGRectMake(0, 0, 300, 70);
        cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:CellIdentifier] autorelease];
        CGRect labLabelFrame = CGRectMake(5, 5, 250, 40);
        UILabel *lblTemp;

        lblTemp = [[UILabel alloc] initWithFrame:labLabelFrame];
        lblTemp.tag = 1;
        [cell.contentView addSubview:lblTemp];
        [lblTemp release];

        CGRect textFieldFrame= CGRectMake(200, 5, 120, 30);

        UITextField *txt=[[UITextField alloc] initWithFrame:textFieldFrame];
        text.tag=2;
        [cell.contentView addSubview:txt];
        [txt release];

    }
     UILabel *cellLabel = (UILabel *)[cell viewWithTag:1];
      UITextField *aField=(UITextField *)[cell viewWithTag:2];

    aField.text=@"";
    aField.placeholder=@"";
if (indexPath.section == 0)
              {
                  if(indexPath.row == 0)
                  {
                      cellLabel.text = @"Tmail";


                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];

                  }
                  else if ( indexPath.row == 1 )
                  {
                      cellLabel.text = @"English";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];


                  }
                  else
                  {
                      cellLabel.text = @"Hindi";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];


                  }
              }
              else if (indexPath.section == 1)
              {
                  if(indexPath.row == 0)
                  {
                      cellLabel.text = @"Street";


                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];

                  }
                  else if ( indexPath.row == 1 )
                  {
                      cellLabel.text = @"City";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];


                  }
                  else
                  {
                      cellLabel.text = @"State";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];

                  }
              }
              else if (indexPath.section == 2)
              {
                  if(indexPath.row == 0)
                  {
                      cellLabel.text = @"Salem";
                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];

                  }
                  else if ( indexPath.row == 1 )
                  {
                      cellLabel.text = @"Samalpatti";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];


                  }
                  else
                  {
                      cellLabel.text = @"Chennai";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];


                  }
              }

              else if (indexPath.section == 3)
              {
                  if(indexPath.row == 0)
                  {
                      cellLabel.text = @"NOKIA";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];

                  }
                  else if ( indexPath.row == 1)
                  {
                      cellLabel.text = @"SAMSUNG";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];


                  }
                  else
                  {
                      cellLabel.text = @"SONY";

                      aField.placeholder = @"Mandatory";
                      aField.delegate = self;
                      aField.textColor = [UIColor blackColor];

                  }
              }


          return cell;
        }

【讨论】:

  • @Ishu :感谢老兄的回复..它可以工作,但是在 uitextfiled 中输入文本后,当滚动 uitable 视图时,我得到文本重叠问题..有什么想法吗?
  • @Ishu 这段代码有问题。如果用户滚动表格,UITextField 中的文本将消失。这些适用于静态数据,但不适用于 UITextFieldUITextView 或用户更改的内容。
  • @brabaghal,在 cell==nil case 中添加 textFields 并添加标签。
  • @Ishu:如果将来他可能不得不添加 10 个以上的部分怎么办?他是否应该在 cellforRowAtIndex 方法中添加 10*3 个标签并添加 10*3 个 nil 检查?
  • @Manjunath,为什么他需要检查 10*3 次并且部分中的增量不会影响单个单元格视图,现在在一个单元格中只有一个标签和文本字段,所以只有两个标签足够了。
【解决方案2】:

您的代码有问题:

1) 单元正在被重用。但是您添加为子视图的文本字段不会被删除!

2) 每当您的 cellforRowAtIndex 被调用时,您每次都在添加文本字段。但是您忘记了您已经添加了一个文本字段但尚未将其删除。

  • 这就是重叠的原因。

解决方案: 子类化 UITableViewCell 并在其 initWithFrame 方法中添加文本字段并将数据传递给该单元格。这将解决您的问题,也将减少您的 cellForRowAtIndex 方法长度。

示例代码: CustomCell.h:

#import <UIKit/UIKit.h>

@class contactr;
@interface CustomTableCell : UITableViewCell 
{
    UITextField *mTextField;
}
@property(nonatomic , retain) UITextField *textField;

@end

CustomCell.m:

#import "CustomTableCell.h"
@synthesize textField = mTextField;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
    {       
        UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(100,10,200,40)];

        self.textField = textField;
        [textField release];
        [self addSubview:self.textField];

    }
    return self;
}

- (void)dealloc 
{
    self.textfield = nil;
    [super dealloc];
}


@end

使用这个类作为你的 tableViewCell。

而且你的 cellForRowAtIndex 必须是:

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
     NSLog(@"CELL IS NIL %i", indexPath.section);

  static NSString *CellIdentifier = @"Cell";
  CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil)
  {


    cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

   }
 cell.textField.placeholder = @"";
 cell.textField.text = @"";
      if (indexPath.section == 0)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"Tmail";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
          }
          else if ( indexPath.row == 1 )
          {
              cell.text = @"English";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
          }
          else
          {
              cell.text = @"Hindi";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
          }
      }
      else if (indexPath.section == 1)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"Street";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
          }
          else if ( indexPath.row == 1 )
          {
              cell.text = @"City";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
          }
          else
          {
              cell.text = @"State";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;

          }
      }
      else if (indexPath.section == 2)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"Salem";

              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
          }
          else if ( indexPath.row == 1 )
          {
              cell.text = @"Samalpatti";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
              cell.textField.textColor = [UIColor blackColor];

          }
          else
          {
              cell.text = @"Chennai";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
              cell.textField.textColor = [UIColor blackColor];

          }
      }

      else if (indexPath.section == 3)
      {
          if(indexPath.row == 0)
          {
              cell.text = @"NOKIA";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
              cell.textField.textColor = [UIColor blackColor];
          }
          else if ( indexPath.row == 1)
          {
              cell.text = @"SAMSUNG";
              cell.textField.placeholder = @"Mandatory";
              cell.textField.delegate = self;
              cell.textField.textColor = [UIColor blackColor];
          }
          else
          {
              cell.text = @"SONY";
              cell.textField.placeholder = @"Mandatory";
             cell.textField.delegate = self;
              cell.textField.textColor = [UIColor blackColor];
          }
      }




  return cell;
}

【讨论】:

  • @ManjuNath 您的代码不会为第 4 节或更多节生成单元格,因为您将所有代码都写在 cell==nil 中,并且当单元格重用控制不会进入 if 条件时。跨度>
  • @Ishu:是的,你是对的。我只是复制粘贴了他的代码并进行了修改。
  • @Manju Nath,现在这段代码的行为与我的代码相同。没有任何变化
  • UITextField *txt=[[UITextField alloc] initWithFrame:textFieldFrame];文本标签=2; [cell.contentView addSubview:txt]; [txt 发布];在这里,您每次都在创建文本文件。但是之前创建的文本字段呢???你在哪里删除它???不是漏水吗?
  • 那边需要什么标签?
【解决方案3】:

从您的初始代码来看,tableview 的行为正常。
您为前 3 个部分创建单元格,因为它们是可见的,并且表格视图中没有多余的单元格可以重复使用。
但是,每当您滚动到第 4 部分(一开始不可见)时,您就会开始重用单元格(恰好是第 1 部分中未超出屏幕的单元格)。

为了不丢失用户在每个单元格中输入的数据,您需要将每个 UITextField(或至少其中的文本)存储在单独的数组中。当表格需要某个单元格时,您可以在数组中查找文本字段。如果它不存在,请创建并添加一个新的 UITextField。

PS:我希望代码没有任何拼写错误。我在工作,我这里没有mac。



@interface MainViewController : UITableViewController
 {
 NSMutableArray* textFields;
}
@end

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad 
{
  CGRect frameRect = CGRectMake(0,0,320,460);

  UITableView *tableView = [[UITableView alloc] initWithFrame:frameRect   
  style:UITableViewStyleGrouped];
  tableView.delegate = self;
  tableView.dataSource = self;  
  tableView.backgroundColor = [UIColor purpleColor];
  tableView.scrollEnabled = YES;

  self.view = tableView;
  [tableView release];

  [super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return 3;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 4;
}

- (UITextField*)getTextFieldAtIndexPath:(NSIndexPath*)indexPath
{
    if (textFields == nil)
      textFields = [[NSMutableArray alloc] init];

    // Add padding, just in case UITableView doesn't need the cells in order
    while (indexPath.section >= [textFields count])
    {
        [textFields addObject:[NSNull null]];
    }

    // Get the section list
   NSMutableArray* sectionList = [textFields objectAtIndex:indexPath.section]; 

   if (sectionList == [NSNull null])
   {
     sectionList = [[[NSMutableArray alloc] init] autorelease];
     [textFields replaceObjectAtIndex:indexPath.section withObject:sectionList];
   }


   // Now that we have the section list, we need to do the same for the row
    while (indexPath.row >= [sectionList count])
    {
        [sectionList addObject:[NSNull null]];
    }

    UITextField* afield = [sectionList objectAtIndex:indexPath.row];

    if (afield == [NSNull null])
    {
      // If there was no afield stored there, just create a new one  
      afield = [[UITextField alloc] initWithFrame:CGRectMake(100,10,200,40)];
      afield.placeholder = @"Mandatory";
      afield.delegate = self;
      afield.textColor = [UIColor blackColor]; 

      [sectionList replaceObjectAtIndex:indexPath.row withObject:aField];

      [afield release];
    }

    return afield;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
     NSLog(@"CELL IS NIL %i", indexPath.section);

  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  UITextField *aField;

 // If we can't reuse the cell, just create a new one
  if (cell == nil)
  {
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
  }
  else
  {
      // if we are reusing the cell, just remove the old textField to make room for the new one
      [[cell.contentView viewForTag:1234] removeFromSuperview];
  }

  // Get the text field for this cell. The method below will create a new one if it doesn't exist, or just return the existing one if found.
  aField = [self getTextFieldAtIndexPath:indexPath];

  // Just add this textfield to the cell
  [cell.contentView addSubView:aField];

  // Now that we added the textfield, we only need to set the title of the cell. The content of the textField will be cached and moved around.

      if (indexPath.section == 0)
      {
          if(indexPath.row == 0)
              cell.text = @"Tmail";
          else if ( indexPath.row == 1 )
              cell.text = @"English";
          else
              cell.text = @"Hindi";
      }
      else if (indexPath.section == 1)
      {
          if(indexPath.row == 0)
              cell.text = @"Street";
          else if ( indexPath.row == 1 )
              cell.text = @"City";
          else
              cell.text = @"State";
      }
      else if (indexPath.section == 2)
      {
          if(indexPath.row == 0)
              cell.text = @"Salem";
          else if ( indexPath.row == 1 )
              cell.text = @"Samalpatti";
          else
              cell.text = @"Chennai";
      }

      else if (indexPath.section == 3)
      {
          if(indexPath.row == 0)
              cell.text = @"NOKIA";
          else if ( indexPath.row == 1)
              cell.text = @"SAMSUNG";
          else
              cell.text = @"SONY";
      }
   }

  return cell;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2016-03-28
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多