4

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)

Community
  • 1
  • 1
Olga Dalton
  • 829
  • 3
  • 15
  • 25
  • http://cocoawithlove.com/2009/08/adding-shadow-effects-to-uitableview.html – ram Aug 02 '11 at 13:36
  • Try these links. It may help you for what you are searching. http://stackoverflow.com/questions/3436276/uilabel-shadow-from-custom-cell-selected-color http://stackoverflow.com/questions/4925282/showing-shadow-in-a-cell-inside-table-view http://stackoverflow.com/questions/3546880/iphone-uitabelviewcell-layer-shadow – iOS Aug 02 '11 at 13:51

3 Answers3

12

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

Nenad M
  • 3,055
  • 20
  • 26
  • The idea is clear, but the code doesn't work as expected, at least on iOS 5. It actually adds some dark fog ABOVE the sections, not below. And even if I add [self sendSubviewToBack: shadowBackgroundView] to "else" also, it doesn't work either. Seems like the created views are placed behind the background. – HiveHicks Jun 01 '12 at 12:42
  • as mentioned, there is room for improvement to my solution! ;) – Nenad M Jul 02 '12 at 13:07
  • but anyway: are you using the grouped table view style in its default form or do you have for example custom section header/footer views? if so, maybe thats the reason for the "displacement" of the section background shadow view! in the "shadowFrameForSection" play with the section header/footer inset values to create the proper frame/bounds for the background view, by taking into account the frame of your custom views if any! – Nenad M Jul 02 '12 at 13:28
2

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.

the.evangelist
  • 488
  • 5
  • 18
-1

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);
Ascendant
  • 2,430
  • 3
  • 26
  • 34