UITableView滚动时,数据丢失在UITableViewCell上?

时间:2012-03-23 06:38:42

标签: iphone objective-c xcode uitableview

我正在尝试实施基于UITableview的应用程序。在我的tableView中,他们是10个部分,每个部分都有一行。 我想要实现每个部分都有不同类型的ContentView(1-8相同ContentView第9个部分不同ContentView)。我为此做了这个代码。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 10;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    return 1;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier1 = @"Cell1";
    static NSString *CellIdentifier2 = @"Cell2";
    UITextField *textField;
    UITextView *textView;
    NSUInteger section=[indexPath section];
    if(section == 9){
        UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
        //UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
        if(cell==nil){
            cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1]autorelease];
            textView=[[UITextView alloc]initWithFrame:CGRectMake(5, 5, 290, 110)];
            [textView setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor
                                          ]];
            [textView setTag:([indexPath section]+100)];
            [cell.contentView addSubview:textView];
        }else{
            textView=(UITextView*)[cell.contentView viewWithTag:([indexPath section]+100)];
        }
        return cell;
    }else {
        UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
       // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
        if(cell==nil){
            cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2]autorelease];
            textField=[[UITextField alloc]initWithFrame:CGRectMake(5, 5, 290, 50)];
            [textField setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
            [textField setTag:([indexPath section]+100)];
            [cell.contentView addSubview:textField];
        }else{
            textField=(UITextField*)[cell.contentView viewWithTag:([indexPath section]+100)];

        }

        return cell;
    }  


    return nil;

}

我的问题是: 1.在UITextField / UITextView中输入一些内容后,我在UITableView中滚动。那个时间UITableViewCellUITextField / UITextView)中的所有数据都丢失了,除了最后一个单元格数据。 2.如果我创建单元格

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

而不是

 UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];

数据会重复。我怎么能解决这个问题?

5 个答案:

答案 0 :(得分:9)

这一行:

UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];

永远不应出现在您的数据源cellForRowAtIndexPath方法中。

除此之外,您的代码没问题,除了您没有在任何地方设置文本字段值。您需要一个模型(例如10个文本字段值的字符串数组)。编辑文本字段时应更新此模型,并在上面的方法中将值从模型中复制回文本字段的文本属性:

textfield.text = [self.modelArray objectAtIndex:indexPath.section];

答案 1 :(得分:1)

该表以不可预测的方式汇集和重用单元格,以便刚刚从底部滚动的单元格的子视图可能会重新出现在顶部,或者可能会被丢弃。

这就是你看到它部分工作的原因。单元格的子视图工作正常,直到它们的单元格被重用或卸载,然后事情移动到错误的地方或数据消失。

解决方案是您的表的数据源需要保留它自己的数据。这通常是表示模型的数组。您的情况有点不寻常,因为您使用表格中的文本控件作为输入,而不是显示,这更典型。

我建议这样做:

// in @interface
@property (nonatomic, retain) NSMutableArray *sections;

// in @implementation
@synthesize sections=_sections;

// at some point before the view appears
self.sections = [NSMutableArray array];
for (int i=0; i<10; i++) {
    UIControl *textControl;
    if (i<9) {
        textControl=[[UITextView alloc]initWithFrame:CGRectMake(5, 5, 290, 110)];
    } else {
        textControl=[[UITextField alloc]initWithFrame:CGRectMake(5, 5, 290, 50)];
    }
    [textControl setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
    [textControl setTag:i+100];
    [sections addObject:textControl];
    [textControl release];
}

现在你的cellForRowAtIndexPath更简单了:

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

    static NSString *CellIdentifier1 = @"Cell1";
    static NSString *CellIdentifier2 = @"Cell2";

    NSUInteger section=[indexPath section];

    if(section == 9) {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
        if(cell==nil) {
            cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1]autorelease];
        }

    } else {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
        if(cell==nil) {
            cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2]autorelease];
        }
    }  

    // who knows what subview this cell has?  it might not have one, or it might have the wrong one
    // just clean it up to be certain
    for (UIView *view in cell.subviews) {
        [view removeFromSuperView];
    }

    // get the textControl we set up for _this_ section/cell
    UIControl *textControl = [self.sections objectAtIndex:section];

    // now we have a fresh cell and the right textControl.  drop it in
    [cell addSubview:textControl];
    return cell;
}

答案 2 :(得分:0)

嘿,原因是当你的细胞是零时,你正在做这件事吗?但是当单元格不是零时,你不会编写任何代码。

看看这个例子,在这个例子中我在tableview单元格中添加图像视图,因此你可以添加textview或任何其他类似的视图

UITableViewCell * cell =(UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

 UIImageView *imgView; 
   if(cell == nil)
   {
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero              reuseIdentifier:CellIdentifier] autorelease];

   imgView = [[UIImageView alloc] initWithFrame:CGRectMake(100,0,100,62)];
   [imgView setImage:[UIImage imageNamed:@"img.png"]];
   imgView.tag = 55;
   [cell.contentView addSubview:imgView];
   [imgView release];
 } 
 else
 {
    imgView = (id)[cell.contentView viewWithTag:55];
  }

所以showin这里imgView =(id)[cell.contentView viewWithTag:55]; 你必须给你标记并在其他地方写上面显示的代码..

答案 3 :(得分:0)

让您尝试使用以下代码制作单元格标签和文本视图。它对我有用。

     if (tagvalue ==3) {

        static NSString *CellIdentifier = @"Cell3";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle    
        reuseIdentifier:CellIdentifier] autorelease];
        }
        lbl7 = [[UILabel alloc] init];
         [lbl7 setFont:[UIFont boldSystemFontOfSize:20]];
         [cell.contentView addSubview:lbl7];
         lbl7.backgroundColor = [UIColor clearColor];
         lbl7.frame = CGRectMake(120, 5, 0, 40);
         lbl7.tag = 70;
         [lbl7 release];

         lbl8 = [[UILabel alloc] init];
         [lbl8 setFont:[UIFont boldSystemFontOfSize:18]];
         [cell.contentView addSubview:lbl8];
         lbl8.backgroundColor = [UIColor clearColor];
         lbl8.textColor = [UIColor grayColor];
         lbl8.frame = CGRectMake(120, 50, 0, 40);
         lbl8.tag = 80;
         [lbl8 release];

        lbl7 = (UILabel*)[cell.contentView viewWithTag:70];
        lbl8 = (UILabel*)[cell.contentView viewWithTag:80];
        lbl7.text = [[rowsarray objectAtIndex:row]objectForKey:@"name"];
        lbl8.text = [[rowsarray objectAtIndex:row]objectForKey:@"flavour"];
        [lbl7 sizeToFit];
        [lbl8 sizeToFit];

        return cell;
    }
    if (tagvalue ==4) {
        static NSString *CellIdentifier = @"Cell4";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        }
        lbl9 = [[UILabel alloc] init];
         [lbl9 setFont:[UIFont boldSystemFontOfSize:20]];
         [cell.contentView addSubview:lbl9];
         lbl9.backgroundColor = [UIColor clearColor];
         lbl9.frame = CGRectMake(120, 5, 0, 40);
         lbl9.tag = 90;
         [lbl9 release];

         lbl10 = [[UILabel alloc] init];
         [lbl10 setFont:[UIFont boldSystemFontOfSize:18]];
         [cell.contentView addSubview:lbl10];
         lbl10.backgroundColor = [UIColor clearColor];
         lbl10.textColor = [UIColor grayColor];
         lbl10.frame = CGRectMake(120, 50, 0, 40);
         lbl10.tag = 100;
         [lbl10 release];            
        lbl9 = (UILabel*)[cell.contentView viewWithTag:90];
        lbl10 = (UILabel*)[cell.contentView viewWithTag:100];
        lbl9.text = [[rowsarray objectAtIndex:row]objectForKey:@"name"];
        lbl10.text = [[rowsarray objectAtIndex:row]objectForKey:@"flavour"];
        [lbl9 sizeToFit];
        [lbl10 sizeToFit];

        return cell;
    }

答案 4 :(得分:0)

我有同样的问题。它不是表类的问题。问题出在您调用此tableviewcontroller的位置。首先在.h中创建此调用的对象,然后在.m中分配,那就是..

当我在像tbl *t = [self.storyboard...];这样的viewdidload中声明时,我也遇到了同样的问题。但是当我把tbl *t;放进.h问题解决了。