0

Hi I am beginner in objective-c and I am doing expandable list in my project and everything is coming but I want to round corner the Headerview all corner sides along with their expandable cells but according to my code when we expand the cells then cell is coming like First image but I want to display cell when we expand like second image please help me some one and this is my code:-

#import "ViewController.h"

@interface ViewController ()
{
     UITableView *  expandableTableView;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self initialization];
}

-(void)initialization
{
    expandableTableView = [[UITableView alloc]init];
    expandableTableView.frame = CGRectMake(5,15,310,self.view.frame.size.height - 50);
    expandableTableView.dataSource=self;
    expandableTableView.delegate=self;
    expandableTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    [expandableTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

    [expandableTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

    expandableTableView.backgroundColor = [UIColor whiteColor];

    UIEdgeInsets inset = UIEdgeInsetsMake(5, 0, 0, 0);
    expandableTableView.contentInset = inset;

    [self.view addSubview:expandableTableView];


    arrayForBool=[[NSMutableArray alloc]init];
    sectionTitleArray=[[NSArray alloc]initWithObjects:
                       @"India",
                       @"Usa",
                       @"Uae",
                       @"Japan",
                       @"SouthAfrica",
                       @"Jarmany",
                       @"England",
                       @"Rasya",
                       nil];

    for (int i=0; i<[sectionTitleArray count]; i++) {
        [arrayForBool addObject:[NSNumber numberWithBool:NO]];
    }
}

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

    if ([[arrayForBool objectAtIndex:section] boolValue]) {
        return 1;
    }
    else

    return 0;
}

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

    static NSString *cellid=@"hello";

    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellid];
    if (cell==nil) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid];
    }

        BOOL manyCells  = [[arrayForBool objectAtIndex:indexPath.section] boolValue];

        if(!manyCells)
        {
            cell.backgroundColor=[UIColor clearColor];
            cell.textLabel.text=@"";
        }

        else
        {
            cell.textLabel.text=[NSString stringWithFormat:@"%@ %d",[sectionTitleArray objectAtIndex:indexPath.section],indexPath.row+1];
            cell.textLabel.font=[UIFont systemFontOfSize:15.0f];
            cell.backgroundColor=[UIColor lightGrayColor];
            cell.imageView.image=[UIImage imageNamed:@"point.png"];
        }
       cell.textLabel.textColor=[UIColor blackColor];

     [cell.layer setCornerRadius:7.0f];
     [cell.layer setMasksToBounds:YES];

    return cell;
}


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

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

    [arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];

     [expandableTableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([[arrayForBool objectAtIndex:indexPath.section] boolValue]) {
        return 100;
    }
    return 0;
}


- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
    UIView *footerView;

    footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 10)];
    footerView.backgroundColor = [UIColor whiteColor];
    return footerView;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
      return 10;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 40;
}

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

    UIView *sectionView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 280,40)];
    sectionView.tag=section;
    sectionView.backgroundColor = [UIColor lightGrayColor];
    UILabel *viewLabel=[[UILabel alloc]initWithFrame:CGRectMake(10, 0, expandableTableView.frame.size.width-10, 40)];
    viewLabel.backgroundColor=[UIColor clearColor];
    viewLabel.textColor=[UIColor blackColor];
    viewLabel.font=[UIFont systemFontOfSize:15];
    viewLabel.text=[NSString stringWithFormat:@"List of %@",[sectionTitleArray objectAtIndex:section]];
    [sectionView addSubview:viewLabel];
    sectionView.layer.cornerRadius = 5.0;
    sectionView.clipsToBounds = YES;

    UITapGestureRecognizer  *headerTapped   = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sectionHeaderTapped:)];
    [sectionView addGestureRecognizer:headerTapped];

    return  sectionView;
}

- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer{

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
    if (indexPath.row == 0) {
        BOOL collapsed  = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
        for (int i=0; i<[sectionTitleArray count]; i++) {
            if (indexPath.section==i) {
                [arrayForBool replaceObjectAtIndex:i withObject:[NSNumber numberWithBool:!collapsed]];
            }
        }
        [expandableTableView reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
@end

enter image description here

enter image description here

Vidya Sagar
  • 1,699
  • 3
  • 17
  • 28
  • As a completely unrelated note, you should really consider switching to modern Objective-C syntax such as subscripting and using object literals, it will make your code a lot tidier and generally more readable. https://www.bignerdranch.com/blog/objective-c-literals-part-1/ – Steve Wilford Jul 09 '15 at 12:09

3 Answers3

0

In order to render the headers and cells the way you desire you will need to use a layer mask to round the corners rather than the cornerRadius helper. This mask will need change depending on the expanded/collapsed state of the section.

Fortunately it appears you are already keeping track of which sections are expanded/collapsed in the arrayForBool variable. As a side note this is a poor choice of name due to it's lack of clarity, expandedSections might be a better fit.

For the collapsed sections the layer mask will need to round all four corners of the header view.

For the expanded sections the layer mask of the header view will need to round the top two corners, while the layer mask of the cell view will need to round the bottom two corners.

You can use a UIBezierPath +bezierPathWithRoundedRect:byRoundingCorners:cornerRadii: to round certain corners of a layer.

Steve Wilford
  • 8,894
  • 5
  • 42
  • 66
  • I was hoping to set you on the right path rather than provide the exact solution. It seems that [Jaeger's answer](http://stackoverflow.com/a/31316470/2613662) would be a better starting point. – Steve Wilford Jul 09 '15 at 12:07
0

You should use layer.mask instead of layer.cornerRadius. The magic is to use a mask layer with or without the bottom corners rounded depending on the case.

CAShapeLayer * maskLayer = [CAShapeLayer layer];
    maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:yourBounds byRoundingCorners: UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:YourCornersRadius].CGPath;
    cell.layer.mask = maskLayer;

Try this code. It's not perfect but you can use it as an inspiration.

#import "ViewController.h"

@interface ViewController () <UITableViewDelegate, UITableViewDataSource>
{
    UITableView *  expandableTableView;
    NSMutableArray *arrayForBool;
    NSArray *sectionTitleArray;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self initialization];
}

-(void)initialization
{
    expandableTableView = [[UITableView alloc]init];
    expandableTableView.frame = CGRectMake(5,15,310,self.view.frame.size.height - 50);
    expandableTableView.dataSource=self;
    expandableTableView.delegate=self;
    expandableTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    [expandableTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

    [expandableTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

    expandableTableView.backgroundColor = [UIColor whiteColor];

    UIEdgeInsets inset = UIEdgeInsetsMake(5, 0, 0, 0);
    expandableTableView.contentInset = inset;

    [self.view addSubview:expandableTableView];


    arrayForBool=[[NSMutableArray alloc]init];
    sectionTitleArray=[[NSArray alloc]initWithObjects:
                       @"India",
                       @"Usa",
                       @"Uae",
                       @"Japan",
                       @"SouthAfrica",
                       @"Jarmany",
                       @"England",
                       @"Rasya",
                       nil];

    for (int i=0; i<[sectionTitleArray count]; i++) {
        [arrayForBool addObject:[NSNumber numberWithBool:NO]];
    }
}

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

    if ([[arrayForBool objectAtIndex:section] boolValue]) {
        return 1;
    }
    else

        return 0;
}

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

    static NSString *cellid=@"hello";

    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellid];
    if (cell==nil) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid];
    }

    BOOL manyCells  = [[arrayForBool objectAtIndex:indexPath.section] boolValue];

    if(!manyCells)
    {
        cell.backgroundColor=[UIColor clearColor];
        cell.textLabel.text=@"";
    }

    else
    {
        cell.textLabel.text=[NSString stringWithFormat:@"%@ %d",[sectionTitleArray objectAtIndex:indexPath.section],indexPath.row+1];
        cell.textLabel.font=[UIFont systemFontOfSize:15.0f];
        cell.backgroundColor=[UIColor lightGrayColor];
        cell.imageView.image=[UIImage imageNamed:@"point.png"];
    }
    cell.textLabel.textColor=[UIColor blackColor];

    [cell.layer setMasksToBounds:YES];
    CAShapeLayer * maskLayer = [CAShapeLayer layer];
    maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 280, cell.frame.size.height) byRoundingCorners: UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(5, 5)].CGPath;
    cell.layer.mask = maskLayer;

    return cell;
}


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

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

    [arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];

    [expandableTableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([[arrayForBool objectAtIndex:indexPath.section] boolValue]) {
        return 100;
    }
    return 0;
}


- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
    UIView *footerView;

    footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 10)];
    footerView.backgroundColor = [UIColor whiteColor];
    return footerView;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 10;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 40;
}

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

    UIView *sectionView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 280,40)];
    sectionView.tag=section;
    sectionView.backgroundColor = [UIColor lightGrayColor];
    UILabel *viewLabel=[[UILabel alloc]initWithFrame:CGRectMake(10, 0, expandableTableView.frame.size.width-10, 40)];
    viewLabel.backgroundColor=[UIColor clearColor];
    viewLabel.textColor=[UIColor blackColor];
    viewLabel.font=[UIFont systemFontOfSize:15];
    viewLabel.text=[NSString stringWithFormat:@"List of %@",[sectionTitleArray objectAtIndex:section]];
    [sectionView addSubview:viewLabel];
    sectionView.clipsToBounds = YES;

    CAShapeLayer * maskLayer = [CAShapeLayer layer];
        UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight;
    if(![[arrayForBool objectAtIndex:section] boolValue])
        corners |= UIRectCornerBottomLeft | UIRectCornerBottomRight;
    maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:sectionView.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(5, 5)].CGPath;
    sectionView.layer.mask = maskLayer;

    UITapGestureRecognizer  *headerTapped   = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sectionHeaderTapped:)];
    [sectionView addGestureRecognizer:headerTapped];

    return  sectionView;
}

- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer{

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
    if (indexPath.row == 0) {
        BOOL collapsed  = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
        for (int i=0; i<[sectionTitleArray count]; i++) {
            if (indexPath.section==i) {
                [arrayForBool replaceObjectAtIndex:i withObject:[NSNumber numberWithBool:!collapsed]];
            }
        }
        [expandableTableView reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
@end
Jaeger
  • 324
  • 1
  • 10
  • yes it's working but when ever we expand the cell first time data is not loading but second time onwords it's working there is default in this code i think –  Jul 09 '15 at 12:05
  • Yes, probably. The code is only to show you how to do the stuff with the corners. – Jaeger Jul 09 '15 at 12:14
0

Visit Workaround for rounded corners of grouped UITableView, iOS7

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    cell.backgroundColor = [UIColor clearColor];

    CGFloat cornerRadius = 5.0;
    CGRect bounds = CGRectInset(cell.bounds, 5.0, 0.0);

    CGMutablePathRef backPathRef = CGPathCreateMutable();
    CGMutablePathRef contourPathRef = CGPathCreateMutable();
    CGMutablePathRef separatorPathRef = CGPathCreateMutable();

    BOOL addLine = NO;
    if (ALL CORNER) {

        CGPathAddRoundedRect(backPathRef, nil, bounds, cornerRadius, cornerRadius);
        CGPathAddRoundedRect(contourPathRef, nil, bounds, cornerRadius, cornerRadius);
    }

    if (ONLY TOP CORNER) {
        // first row
        CGPathMoveToPoint(backPathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
        CGPathAddArcToPoint(backPathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds), CGRectGetMidX(bounds), CGRectGetMinY(bounds), cornerRadius);
        CGPathAddArcToPoint(backPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
        CGPathAddLineToPoint(backPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));

        CGPathMoveToPoint(contourPathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
        CGPathAddArc(contourPathRef, nil,
                     CGRectGetMinX(bounds) + cornerRadius, CGRectGetMinY(bounds) + cornerRadius,
                     cornerRadius,        // radius
                     M_PI,                // start angle
                     3.0 * M_PI_2,        // end angle
                     NO);                 // clockwise
        CGPathAddArc(contourPathRef, nil,
                     CGRectGetMaxX(bounds) - cornerRadius, CGRectGetMinY(bounds) + cornerRadius,
                     cornerRadius,        // radius
                     3.0 * M_PI_2,        // start angle
                     0.0,                 // end angle
                     NO);                 // clockwise
        CGPathAddLineToPoint(contourPathRef, NULL, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));

        CGPathMoveToPoint(separatorPathRef, nil, CGRectGetMinX(bounds) + bounds.origin.x, CGRectGetMaxY(bounds));
        CGPathAddLineToPoint(separatorPathRef, NULL, CGRectGetMaxX(bounds) - bounds.origin.x, CGRectGetMaxY(bounds));

        addLine = YES;
    }

    if (ONLY BOTTOM CORNER) {
        // last row
        CGPathMoveToPoint(backPathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
        CGPathAddArcToPoint(backPathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds), CGRectGetMidX(bounds), CGRectGetMaxY(bounds), cornerRadius);
        CGPathAddArcToPoint(backPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds), CGRectGetMaxX(bounds), CGRectGetMidY(bounds), cornerRadius);
        CGPathAddLineToPoint(backPathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));

        CGPathMoveToPoint(contourPathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
        CGPathAddArc(contourPathRef, nil,
                     CGRectGetMinX(bounds) + cornerRadius, CGRectGetMaxY(bounds) - cornerRadius,
                     cornerRadius,          // radius
                     M_PI,                  // start angle
                     M_PI_2,                // end angle
                     YES);                  // counterclockwise
        CGPathAddArc(contourPathRef, nil,
                     CGRectGetMaxX(bounds) - cornerRadius, CGRectGetMaxY(bounds) - cornerRadius,
                     cornerRadius,          // radius
                     M_PI_2,                // start angle
                     0.0,                   // end angle
                     YES);                 // counterclockwise
        CGPathAddLineToPoint(contourPathRef, NULL, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));

    } 

    CAShapeLayer *backLayer = [[CAShapeLayer alloc] init];
    backLayer.path = backPathRef;
    backLayer.fillColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;

    CAShapeLayer *contourLayer = [[CAShapeLayer alloc] init];
    contourLayer.path = contourPathRef;
    contourLayer.lineWidth = (1.0 / [UIScreen mainScreen].scale);
    contourLayer.strokeColor = [UIColor clearColor].CGColor;
    contourLayer.fillColor = [UIColor clearColor].CGColor;

    CAShapeLayer *separatorLayer = [[CAShapeLayer alloc] init];
    separatorLayer.path = separatorPathRef;
    separatorLayer.lineWidth = (1.0 / [UIScreen mainScreen].scale);
    separatorLayer.strokeColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;
    separatorLayer.fillColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;

    [backLayer addSublayer:separatorLayer];
    [backLayer addSublayer:contourLayer];

    CAShapeLayer *selectedBackLayer = [[CAShapeLayer alloc] init];
    selectedBackLayer.path = backPathRef;
    selectedBackLayer.fillColor = [UIColor clearColor].CGColor;

    CAShapeLayer *selectedContourLayer = [[CAShapeLayer alloc] init];
    selectedContourLayer.path = contourPathRef;
    selectedContourLayer.lineWidth = (1.0 / [UIScreen mainScreen].scale);
    selectedContourLayer.strokeColor = [UIColor clearColor].CGColor;
    selectedContourLayer.fillColor = [UIColor clearColor].CGColor;

    [selectedBackLayer addSublayer:selectedContourLayer];

    CGPathRelease(backPathRef);
    CGPathRelease(contourPathRef);

    UIView *testView = [[UIView alloc] init];
    [testView.layer insertSublayer:backLayer atIndex:0];
    testView.backgroundColor = [UIColor clearColor];
    cell.backgroundView = testView;

    UIView *selectedView = [[UIView alloc] init];
    [selectedView.layer insertSublayer:selectedBackLayer atIndex:0];
    selectedView.backgroundColor = [UIColor clearColor];

    cell.selectedBackgroundView = selectedView;
}

}

Community
  • 1
  • 1
Ptbaileys
  • 41
  • 1
  • 3