Olga Dalton
Olga Dalton

Reputation: 849

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)

Upvotes: 4

Views: 9291

Answers (3)

Ascendant
Ascendant

Reputation: 2579

In cellForRowAtIndexPath: function:

// drop shadow
cell.layer.shadowOpacity = 1.0;
cell.layer.shadowRadius = 1.7;
cell.layer.shadowColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0.0, 0.0);

Upvotes: -1

Nenad M
Nenad M

Reputation: 3055

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! :-)

Upvotes: 12

the.evangelist
the.evangelist

Reputation: 488

Easiest one would be add drop-shadow styling to the layer to your cells in table. Remember you would have 3 types of styling - one for the top of the cell, one for the bottom cell and one for the other cells. Should not be very difficult if you start writing the code.

Upvotes: 2

Related Questions