Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
593 views
in Technique[技术] by (71.8m points)

iphone - 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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...