简体   繁体   English

展开单元格时,UITableView单元格未在某些单元格中显示数据

[英]UITableView cells not showing data in some cells when a cell is expanded

I load a expanded cell XIB during didSelectRowAtIndexPath in my tableView .Now when every cell expands I call a webservice.Depending on the response of it, I load a childViewController in the expanded cell .Now the problem is that the data is visible in certain cells and it isn't in other cells? 我在tableView didSelectRowAtIndexPath期间加载了一个扩展的单元格XIB 。现在每个单元格扩展时我都调用一个Web服务,根据它的响应,我在扩展的单元格中加载了childViewController 。现在的问题是数据在某些单元格中可见它不在其他单元中吗? I am not entirely sure whether dequeueReusableCellWithIdentifier ie re-using of cells is causing such a problem.But if that is , How can I solve the problem? 不完全确定dequeueReusableCellWithIdentifier重复使用单元格是否会导致此类问题。但是,如果那样,我该如何解决该问题?

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

static NSString *cellIdentifier = @"Cell";
static NSString *expandedCellIdentifier = @"ExpandedCell";
if (!isExpanded) {

  ListCell *cell =(ListCell*) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell==nil) {
        NSArray *nibs = [[NSBundle mainBundle]loadNibNamed:@"ListCell" owner:self options:nil];
        cell = nibs[0];

    }
 cell.Name.text = [[bArray objectAtIndex:indexPath.row]valueForKey:@"opName"];
 return cell;

  }

 else{

 expCell = (ExpandedCell*)[tableView dequeueReusableCellWithIdentifier:expandedCellIdentifier];
 if (expCell==nil) {
        NSArray *nibs = [[NSBundle mainBundle]loadNibNamed:@"ExpandedCell" owner:self options:nil];
        expCell = nibs[0];

     UILabel *end = [[UILabel alloc]initWithFrame:CGRectMake(90, 24, 70, 14)];

    [end setTag:102];

    [expCell.background_View addSubview:end];

  }
    UILabel *endLabel = (UILabel *)[expCell.background_View viewWithTag:102];
    endLabel.text = [NSString stringWithFormat:@"%@",endStn.capitalizedString];

    return expCell;

}

return nil;

}


 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

if ([self.expandedCells containsObject:indexPath]) {

    [self.expandedCells removeAllObjects];
 }else{
    isExpanded=YES;

    if (self.expandedCells.count>0) {
        [self.expandedCells removeAllObjects];
    }

    [self.expandedCells addObject:indexPath];

    //Call webservice and populate the view controller to be loaded.
     [self callWebservice completionBlock:^(BOOL finished){

        if (finished) {


            [self initialseChildViewController:^(BOOL finished){
                if (finished) {

                    [self populateView:^(BOOL finished){

                        if (finished) {

                            if (expCell.expContainer.hidden==YES) {
                                expCell.expContainer.hidden=NO;
                            }


                        }else{
                            NSLog(@"Data not populated");
                        }

                    }];


                }else{
                    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"" message:@"ChildViewController not initialised" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                    [alert show];
                }

            }];


        }

    }];
    [self.busTableView beginUpdates];
    [self.busTableView reloadData];
    [self.busTableView endUpdates];

}

Modify your code as below. 如下修改您的代码。 You need to return..cell in first if condition.. You are returning nil at if (!isExpanded) condition. 您需要首先在if条件中返回.cell。在if(!isExpanded)条件下返回nil。 Fix as below 修复如下

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

static NSString *cellIdentifier = @"Cell";
static NSString *expandedCellIdentifier = @"ExpandedCell";
if (!isExpanded) {

  ListCell *cell =(ListCell*) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell==nil) {
        NSArray *nibs = [[NSBundle mainBundle]loadNibNamed:@"ListCell" owner:self options:nil];
        cell = nibs[0];

    }
 cell.Name.text = [[bArray objectAtIndex:indexPath.row]valueForKey:@"opName"];

return cell;

  }

 else
{

 expCell = (ExpandedCell*)[tableView dequeueReusableCellWithIdentifier:expandedCellIdentifier];
 if (expCell==nil) 
  {
        NSArray *nibs = [[NSBundle mainBundle]loadNibNamed:@"ExpandedCell" owner:self options:nil];
        expCell = nibs[0];
  } 

    UILabel *endLabel = (UILabel *)[expCell.background_View viewWithTag:102];
    endLabel.text = [NSString stringWithFormat:@"%@",endStn.capitalizedString];

    return expCell;

}

return nil;

}

Hope it helps you.. 希望对您有帮助。

Anything you do to the cells in didSelectRow is suspect, especially things you do asynchronously. 您对didSelectRow中的单元格所做的任何事情都是可疑的,尤其是您异步进行的事情。 Those cells come and go while the user scrolls. 当用户滚动时,这些单元格会进出。 The state changes you make directly to cells will show up elsewhere when the cell is reused in another indexPath. 当单元在另一个indexPath中重用时,直接对单元进行的状态更改将显示在其他位置。

Instead, the pattern that you should follow is: (1) user takes action, (2) action changes model, (3) model change causes the table update, (4) table update reads the model. 相反,您应该遵循的模式是:(1)用户采取行动,(2)行动改变模型,(3)模型改变导致表更新,(4)表更新读取模型。

In this case, that means that this code... 在这种情况下,这意味着此代码...

 [self callWebservice completionBlock:^(BOOL finished){
     if (finished) {
         [self initialseChildViewController:^(BOOL finished){
             if (finished) {
                 [self populateView:^(BOOL finished){

...should not refer to any table cells (neither in the methods, nor in the completion blocks). ...不应引用任何表单元格(无论是在方法中还是在完成块中)。 The only cell-modifying code you've posted is in the next lines: 您发布的唯一修改单元格的代码在以下几行中:

                     if (expCell.expContainer.hidden==YES) {
                         expCell.expContainer.hidden=NO;
                     }

...and even those must change. ...甚至那些必须改变。 Whatever it is you're doing to the cell right there must instead be done in cellForRowAtIndexPath. 无论您对单元格做什么,都必须在cellForRowAtIndexPath中完成。 Make a note in your model that the hidden state of the cell's expContainer at this indexPath must change (not sure if that's equiv in your project to adding to the expandedCells collection), then reload the row at this indexPath. 在模型中记下该indexPath处的单元格expContainer的隐藏状态必须更改(不确定在您的项目中是否等同于添加到expandedCells集合中),然后在此indexPath处重新加载该行。

To restate the rule: only change cells in cellForRowAtIndexPath. 重新声明规则:仅更改cellForRowAtIndexPath中的单元格。 Change those cells according to the model (aka the datasource array). 根据模型(即数据源数组)更改这些单元格。 If there's insufficient info in the model to tell you how to configure a cell, then your model is missing something... add it to your model. 如果模型中的信息不足以告诉您如何配置单元,则您的模型缺少某些内容……将其添加到模型中。 Then, when you want to do anything to a table cell, don't do it. 然后,当您想对表格单元做任​​何事情时,就不要这样做。 Do something to your model, and then that part of the table to reload. 对您的模型做些事情,然后重新加载表的那部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM