Mrunal
Mrunal

Reputation: 14118

Multiple UITableViewCell in single UITableView using storyboard feature

I am having view similar like:

enter image description here

As you can see, there are various sections

And UI for all these 3 cells are little bit different.

I have created 1 UITableView in my storyboard, in that 3 different cell also been added with required designing.

Now what next to do, i have already search for this, what I found is older solutions which we used to use for xibs (3 diff xibs for each cell)

Note- Main issue is like how to create a box around the course data. Each box refers to particular course only. Inside the box (course), there is a subject list placed in bordered cell. How to achieve such scenario using CellIdentifier and storyboard?

Let me know generic solution which I can apply for storyboard.

Regards,

Mrunal

Upvotes: 1

Views: 1653

Answers (2)

Prince Kumar Sharma
Prince Kumar Sharma

Reputation: 12641

You can use ImageView to do this :----

- (void)viewDidLoad
{
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier];


    classes=[[NSArray alloc] initWithObjects:@"Class1",@"Class2",@"Class3",@"Class4",@"Class5",nil];
    courses=[[NSArray alloc] initWithObjects:@"Diploma",@"B.Tech",@"NIIT",@"Web Designing",@"Animation", nil];
    subjects=[[NSArray alloc] initWithObjects:@"Math",@"Applied Physics",@"Communication Skills", nil];

    [_tableView reloadData];

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [classes count];
}

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


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];


    UILabel *label;
    label=(UILabel*)[cell viewWithTag:22];

    UIImageView *backImg;

    backImg=(UIImageView*)[cell viewWithTag:21];

    CGPoint origin=cell.textLabel.frame.origin;

    int leftOffset=20;

    if (!backImg) {
        backImg=[[UIImageView alloc] initWithFrame:CGRectMake(origin.x+leftOffset, origin.y, 150, 30)];
        backImg.tag=21;
        backImg.image=[UIImage imageNamed:@"back.png"];

        label=[[UILabel alloc] initWithFrame:backImg.frame];
        label.tag=22;
        label.backgroundColor=[UIColor clearColor];

        [cell addSubview:backImg];
        [cell addSubview:label];
    }

    CGSize size=[[courses objectAtIndex:indexPath.section] sizeWithFont:label.font constrainedToSize:CGSizeMake(MAXFLOAT, 30) lineBreakMode:label.lineBreakMode];

    if (indexPath.row==0) {
        [backImg setFrame:CGRectMake(origin.x+leftOffset, 5, size.width, size.height)];
        label.text=[courses objectAtIndex:indexPath.section];
    }else{
        [backImg setFrame:CGRectZero];
        label.text=[subjects objectAtIndex:indexPath.row-1];
    }

    return cell;
}


- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{

    UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
    label.font=[UIFont boldSystemFontOfSize:17.0];
    label.text=[classes objectAtIndex:section];
    label.backgroundColor=[UIColor clearColor];

    CGSize size=[[classes objectAtIndex:section] sizeWithFont:label.font constrainedToSize:CGSizeMake(MAXFLOAT, 30) lineBreakMode:label.lineBreakMode];

    NSLog(@"size at section %i is %@",section,NSStringFromCGSize(size));

    UIImageView *imgView;
    imgView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 5, size.width, size.height)];

    [imgView setImage:[UIImage imageNamed:@"back.png"]];

    UILabel *backView=[[UILabel alloc]initWithFrame:label.frame];
    [backView setBackgroundColor:[UIColor clearColor]];

    [backView addSubview:imgView];
    [backView addSubview:label];
    return backView;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [classes objectAtIndex:section];
}

screenshot---

enter image description here

Here is Img

Upvotes: 2

Gianluca Tranchedone
Gianluca Tranchedone

Reputation: 3598

To have different cells to work nicely in a UITableView, you should use a different reuse identifier for each cell. In Storyboards you can simply set this property on the cell using the inspector. In code, you should do it in -tableView:cellForRowAtIndexPath:.

This will make the table work nice when you scroll through the cells and not have weird things to happen. This way courses of of a given type will only be displayed using one kind of cell.

For example, in code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString * const Course1CellIdentifier = @"Course1Cell";
    static NSString * const Course2CellIdentifier = @"Course2Cell";
    static NSString * const Course3CellIdentifier = @"Course3Cell";

    NSString *reuseIdentifier = nil;
    Course *course = ...; // some logic
    if (/*check if is course 1*/) {
        reuseIdentifier = Course1CellIdentifier;
    }
    else if (/*check if is course 2*/) {
        reuseIdentifier = Course2CellIdentifier;
    }
    else {
        reuseIdentifier = Course1CellIdentifier;
    }

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWitStyle:UITableViewStyleDefault reuseIdentifier:reuseIdentifier];
    }

    ...

    return cell;
}

Moreover, for your cells, you might want to create a custom abstract cell for your courses (a class you actually don't use) that you subclass to have the different courses to be displayed differently (e.g. different cell's height, border, background, whatever).

Upvotes: 0

Related Questions