Navjot Singh
Navjot Singh

Reputation: 65

multiple cell identifier in tableview in iOS

I am using a array containing objects from two dictionaries and displaying objects of first dictionary on first cell having different identifier and same with second dictionary objects.

check out my code in cellforrowatindexpath

static NSString *cellIdentifier = @"cellIdentifier1";
    static NSString *customCellIdentifier = @"cellIdentifiercustom";

    if (indexPath.row == 0) {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        //        if (cell==nil)
        {
            cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];

        }
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        ExcName = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 2.0, 250.0, 36.0)];
        ExcName.font = [UIFont systemFontOfSize:12.0];
        ExcName.textColor = [UIColor blackColor];
        ExcName.textAlignment = NSTextAlignmentLeft;
        ExcName.text=[[exerciseAr objectAtIndex:indexPath.row] objectForKey:@"activityname"];
        ExcName.numberOfLines=3;
        [cell.contentView addSubview:ExcName];

        return  cell;
    }
    else{
        UITableViewCell *customcell = [tableView dequeueReusableCellWithIdentifier:customCellIdentifier];

        //        if (cell==nil)
        {
            customcell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:customCellIdentifier];

        }
        customcell.selectionStyle = UITableViewCellSelectionStyleNone;
        ExcName = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 2.0, 250.0, 36.0)];
        ExcName.font = [UIFont systemFontOfSize:12.0];
        ExcName.textColor = [UIColor blackColor];
        ExcName.textAlignment = NSTextAlignmentLeft;
        ExcName.text=[[exerciseAr objectAtIndex:indexPath.row] objectForKey:@"exercisename"];
        //    ExcName.text=[[exerciseAr objectAtIndex:indexPath.row] objectForKey:@"exercisename"];

        ExcName.numberOfLines=3;
        [customcell.contentView addSubview:ExcName];

                return  customcell;
    }

    return nil;
}

now I want if any dictionary is null, cell corresponding to that dictionary should not be visible which is visible now.

Upvotes: 0

Views: 1505

Answers (2)

Natasha
Natasha

Reputation: 6893

It actually depends what you meant by your dictionary being null. It may be nil, or it just doesn't have any values for the keys e.g the values for the key is an empty string. So, to add to NibolasMiari's answer, I would say, check both of the cases.

- (void) filterDictionaries:(NSArray*) exerciseAr{
    filteredArray = [[NSMutableArray alloc]init];

    for (NSDictionary* myDict in exerciseAr) {
        if ([myDict isKindOfClass:[NSNull class]]) {
           continue;
        }
        else if ([myDict count] == 0) {
            continue;
        }
        else{
            [filteredArray addObject: myDict];
        }
    }   
}

- (NSInteger) tableView:(UITableView*) tableView numberOfRowsInSection:(NSInteger) section
{
    return [filteredArray count];
}

Now in your cellforIndexPath method everything will be same just changed the lines following way-

In the if block, you had

ExcName.text=[[exerciseAr objectAtIndex:indexPath.row] objectForKey:@"activityname"];

Make it -

ExcName.text=[[filteredArray objectAtIndex:indexPath.row] objectForKey:@"activityname"];

In the else block, you had

ExcName.text=[[exerciseAr objectAtIndex:indexPath.row] objectForKey:@"exercisename"];

Make it -

ExcName.text=[[filteredArray objectAtIndex:indexPath.row] objectForKey:@"exercisename"];

Upvotes: 1

Nicolas Miari
Nicolas Miari

Reputation: 16256

A few things:

  1. Don't return nil from -tableView:cellForRowAtIndexPath:. That method gets called exactly once for each (visible) row, and the table assumes it has as many rows as you told throught the return value of -tableView:numberOfRowsInSection:. Defaulting to nil reveals an inconsistency in your code.

  2. By that token, cell dequeueing should never fail. I recommend that you switch to the newer method: -dequeueReusableCellWithIdentifier:forRowAtIndexPath:. It takes care of allocation of new cells for you when there is no cell in the reuse pool.

  3. Cells are being reused. A single cell may be reuse multiple times: If you add a new label each time, they will pile up. Instead, add the label to your cells in interface builder and set up an outlet to reference them when configuring the cell.


The Solution:

Instead of "skipping rows", make your data model consistent with what you are going to display. If you have an array with objects some of which you want to skip, first filter your array and then used the filtered array as data source.

// Call this method once before reloading the table view
- (void) filterDictionaries
{
    // (filteredArray is an ivar defined as NSMutableArray*)

    for (NSDictionary* dictionary in exerciseAr) {
    
        if ([dictionary  objectForKey:@"exercisename"] != nil) {
            [filteredArray addObject: dictionary];
        }
    }   
    // Now you can use filteredArray as the data source 
    // instead of exerciseAr, without worrying about skipping 
    // entries.
}

- (NSInteger) tableView:(UITableView*) tableView numberOfRowsInSection:(NSInteger) section
{
    return [filteredArray count];
}
 
- (UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
    static NSString *cellIdentifier = @"cellIdentifier1";
    static NSString *customCellIdentifier = @"cellIdentifiercustom";

    UITableViewCell* cell;

    if (indexPath.row == 0) {
        cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forRowAtIndexPath:indexPath];
    }
    else{
        cell = [tableView dequeueReusableCellWithIdentifier:customCellIdentifier forRowAtIndexPath:indexPath];
    }
    
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
      
    cell.excLabel.text =  [[filteredArray objectAtIndex:indexPath.row]
    
    return  cell;
}

Upvotes: 2

Related Questions