【问题标题】:UITableView cell/data disappearUITableView 单元格/数据消失
【发布时间】:2011-04-13 11:09:49
【问题描述】:

我有一个分段的 tableView,它加载所有部分的所有单元格中的所有数据。 每个单元格中都有一个 textField。

tableview 不完全适合 iPad 屏幕,我无法访问所有不可见的单元格以读取/保存数据。当我在“textField”中进行更改时,向上滚动,向下滚动,所有更改都消失了。

我需要加载所有单元格,甚至一次不可见,才能访问它们。

对不起,我几天前才开始使用表格... 我认为这个问题与可重复使用的细胞有关,但不知道如何解决。

请寻求您的帮助。

初始化:

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

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


    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
        textField.enabled = NO;
        cell.accessoryView = textField;
        [textField release];

}
    UITextField *textField = (UITextField*)cell.accessoryView;

    if(indexPath.section == 0)
        cell.textLabel.text = [idenInfo objectAtIndex:indexPath.row];
    else if (indexPath.section == 1)
        cell.textLabel.text = [prodInfo objectAtIndex:indexPath.row];
    else if (indexPath.section == 2)
        cell.textLabel.text = [visInfo objectAtIndex:indexPath.row];


    if(indexPath.section == 0)
        textField.text = [idenInfoRez objectAtIndex:indexPath.row];
    else if (indexPath.section == 1)
        textField.text = [prodInfoRez objectAtIndex:indexPath.row];
    else if (indexPath.section == 2)
        textField.text = [visInfoRez objectAtIndex:indexPath.row];

    textField = nil;

    return cell;
}

【问题讨论】:

    标签: iphone objective-c ios ipad uitableview


    【解决方案1】:

    首先:您不必加载所有单元格,包括不可见的单元格。这就是 UITableView 和 MVC 模式的重点:将视图与数据分开。

    当用户更改文本字段中的值时,您需要做的是更新您的数据源(即idenInfoRezprodInfoRezvizInfoRez)。因此,您必须将 UIViewController 设置为每个文本字段的委托,并在用户输入时更新值。

    【讨论】:

    • 我如何知道哪个单元格的 (indexPath) textField 调用了该事件?那么我实际上可以修改对应的数据源吗?
    • 查看 UITableViewDataSource 协议方法。您将找到需要实现的方法,以了解表中的用户操作修改了哪个 indexPath。我也会做一些阅读。 iOS 应用程序编程指南描述了 MVC 设计模式。 Table View Controller Programming Guide 是表的最佳起点。
    【解决方案2】:

    [UIView beginAnimations:@"ShiftUp" context:nil]; [UIView setAnimationDuration:0.0001]; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger section = [indexPath section];

    static NSString *CellIdentifier = @"Cell";
    
    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    

    如果(单元格 == nil){

        [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = objCustCell;
       cell.selectionStyle = UITableViewCellSelectionStyleNone ;
    

    }

    if (section == 0) {
    
           switch (indexPath.row) {
               case 0:{
    
                cell.lable.text = @"Date of Birth";
                cell.field.placeholder = @"Birth Name";
    
                   break;
               }
    
               case 1:{
    
                   cell.lable.text = @"Enter Your Name";
                   cell.field.placeholder = @"Full Name";
    
                   break;
               }
    
    
               default:
                   break;
           }
    
     }
    
    [UIView beginAnimations:@"ShiftUp" context:nil];
    [UIView setAnimationDuration:0.0001];
    
    //  [UIView beginAnimations: @"ShiftUp" context:nil];
    
    NSLog(@"Load cellfor raw at index  ");
    // Configure the cell.
           return cell;
    

    }

    注意:UIView 动画将不允许文本字段移走数据,否则任何 UIcontroller 将保持其旧状态! 不要提交动画,否则它将无法正常工作!

    【讨论】:

      【解决方案3】:

      您可以这样做:在每个 TextField 的 Editing Changed 事件中,将包含在文本字段中的值存储在 NSMutableArray 中,其数量等于单元格的数量。即

      -(IBAction) EditingChanged: (id) sender
      
      {
      
         UITextField *txt =(UITextField*)sender;
      
         NSString* str =[[NSString alloc] initWithString: txt.text]; 
         //get current text string
      
         NSInteger path =[tableView indexPathForSelectedRow].row;
                // get currently selected row, this could be a bit different depending on the number of sections
      
         [yourMutableArray insertObject: str atIndex: path]; 
      
         [str release]
      
      }
      

      然后,您可以在重新创建单元格时使用NSMutableArray 中的值填充TextField,即

      (UITableViewCell *) tableView: (UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
      
      {
      
         ...... // create the cells here and use viewTag to get the textFields
      
         textField.text= [yourMutableArray objectAtIndex:indexPath.row];
      
         //This may be a bit different depending on the number of sections.
      
      }
      

      另外,请注意,最好将yourMutable 数组初始化为单元格数量的容量。

      如果代码格式不正确,我很抱歉,因为这是我在 stackoverflow 上的第一篇文章 - 代码中可能存在一些拼写错误。希望这对某人有所帮助。

      【讨论】:

        【解决方案4】:

        每次我们为不同的数据分配单元格时,数据不会重新加载单元格,每次数据覆盖之前的数据,在分配单元格之前清除单元格, 就像 cell=nil

               - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        
                    static NSString *CellIdentifier = @"Cell";
                    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        
                   cell=nil;
                //it clear data in the cell
                    if (cell == nil)
         {
                        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
                        UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
                        textField.enabled = NO;
                        cell.accessoryView = textField;
                        [textField release];
        
                }
        

        【讨论】:

          【解决方案5】:

          你是对的,问题是细胞会被重复使用。这个问题有两种解决方案,一种快速而肮脏的方法是不使用可重复使用的细胞:

          删除这个:

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

          然后离开这个:

             UITableViewCell * cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
              UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
              textField.enabled = NO;
              cell.accessoryView = textField;
              [textField release];
          

          如果您的表格视图中只有少量单元格(大约少于 50 个),那应该没问题。


          更好的解决方案是保持单元格重用,并根据要求填写其文本字段。该方法因应用程序而异,但您基本上永远不应该直接访问单元格,并将单元格的数据存储在其他地方,例如NSString 的 NSArray。然后你可以操作 NSArray。您的 cellForRowAtIndexPath 方法看起来像这样:

          textField.text = [arrData objectAtIndex:indexPath.row];
          

          【讨论】:

          • 如果我删除静态 NSString *CellIdentifier = @"Cell";我无法使用您的代码进行初始化。因为 CellIdentifiel 不存在。如果我保留它,但删除“if”,问题就没有解决。 (我只有 13 个单元格)
          • 只需传递nil 作为参数。请注意,如果它以后包含的行数明显多于当前的 13 行,这样做会使您的表视图非常低效。
          • 单元格仍然无法访问,滚动后数据仍然会重新加载。
          • 完全错误的答案。当用户进行更改时,您需要正确更新您的数据模型。当你这样做时,表格将正确加载。
          猜你喜欢
          • 2017-06-15
          • 1970-01-01
          • 1970-01-01
          • 2011-07-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多