Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouped uitableview with shadow

Any ideas how to show a shadow around the grouped uitableview's border?(around all border at top, bottom, sides as well as around rounded corners of sections).

I need exactly the same effect like here on the picture:

alt

Pay attention to small shadow near the border(gray one, blue is the background)

like image 432
Olga Dalton Avatar asked Dec 09 '22 07:12

Olga Dalton


1 Answers

i came up with a rather "hackish" solution to this in my opinion, so i'm not totally happy with it but anyway! the basic functionality of drawing a drop shadow around a group of cells in a section is acomplished by that. therefore i subclassed UITableView and implemented the layoutSubviews method like this:

- (void) layoutSubviews {
    [super layoutSubviews];

    const CGFloat PageCellBackgroundRadius = 6.0;

    for(int i = 0; i < [self numberOfSections]; i++) {
        NSInteger viewTag = i + 123456;
        CGRect frameRect = [self shadowFrameForSection: i];

        UIView* shadowBackgroundView = [self viewWithTag: viewTag];
        if (shadowBackgroundView) {
            if (!CGRectEqualToRect(frameRect, shadowBackgroundView.frame)) {
                shadowBackgroundView.frame = frameRect;
                CGPathRef shadowPath = [UIBezierPath bezierPathWithRoundedRect: shadowBackgroundView.bounds 
                                                             byRoundingCorners: UIRectCornerAllCorners
                                                                   cornerRadii: CGSizeMake(PageCellBackgroundRadius, PageCellBackgroundRadius)].CGPath;
                shadowBackgroundView.layer.shadowPath = shadowPath;
            }

            [self sendSubviewToBack: shadowBackgroundView];
        } else {
            shadowBackgroundView = [[[UIView alloc] initWithFrame: frameRect] autorelease];
            shadowBackgroundView.tag = viewTag;
            shadowBackgroundView.opaque = YES;
            shadowBackgroundView.backgroundColor = [UIColor clearColor];

            shadowBackgroundView.layer.shadowOpacity = 0.3; 
            shadowBackgroundView.layer.shadowRadius = 2;
            shadowBackgroundView.layer.shadowColor = [[UIColor blackColor] CGColor];
            shadowBackgroundView.layer.shadowOffset = CGSizeMake(0.0, 1.0);
            CGPathRef shadowPath = [UIBezierPath bezierPathWithRoundedRect: shadowBackgroundView.bounds 
                                                         byRoundingCorners: UIRectCornerAllCorners
                                                               cornerRadii: CGSizeMake(PageCellBackgroundRadius, PageCellBackgroundRadius)].CGPath;
            shadowBackgroundView.layer.shadowPath = shadowPath;
            shadowBackgroundView.layer.shouldRasterize = YES;

            [self addSubview: shadowBackgroundView];
        }
    }
}

and a little helper method:

- (CGRect) shadowFrameForSection: (NSInteger) section {
    CGRect sectionFrame = [self rectForSection: section];

    CGFloat sectionHeaderHeight = CGRectGetHeight([self rectForHeaderInSection: section]);
    CGFloat sectionFooterHeight = CGRectGetHeight([self rectForFooterInSection: section]);

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(sectionHeaderHeight + 1, 10, sectionFooterHeight + 1, 10);
    return UIEdgeInsetsInsetRect(sectionFrame, contentInsets);
}

the code is self-explanatory i think! basically it revolves around adding UIViews to the UITableView as subviews, for a calculated frame of a section, and then drawing the drop shadow to the layer of the added UIView. UITableView provides some methods for the frame calculations: "rectForSection" etc.

i'm not happy with it because it feels not right adding views in the layoutSubviews method! (this could be done somwhere else => table view delegate?) i also would have liked more to work with CALayers, but you can't tag them! because my code works by shrinking/expanding already added uiviews for performance reasons.

in this form, the solution won't work if sections disappear or if sections are reorderd etc. it also behaves not well if you're adding rows in a animated fashion to the table view etc. but it's quite useful for "static" grouped table views i think!

i also haven't tested for performance implications, so use at own risk!

so maybe this is a good starting point for a possibly better solution to this! :-)

like image 157
Nenad M Avatar answered Dec 29 '22 02:12

Nenad M