简体   繁体   中英

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? 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?

- (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. 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. 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.

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.

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. 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.

To restate the rule: only change cells in 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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