0
votes

I'm building an iPad app that includes several bar graphs (30+ bars per graph) and a pull-up menu from the bottom of the screen. The design calls for these bars to have rounded corners on the top left and top right corner, but square corners on the bottom left and bottom right.

Right now, I am rounding the top corners of each individual graph bar by using a mask layer:

#import "UIView+RoundedCorners.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIView (RoundedCorners)

-(void)setRoundedCorners:(UIRectCorner)corners radius:(CGFloat)radius {
    CGRect rect = self.bounds;

    // Create the path 
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect 
                                                   byRoundingCorners:corners
                                                         cornerRadii:CGSizeMake(radius, radius)];

    // Create the shape layer and set its path
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = rect;
    maskLayer.path = maskPath.CGPath;

    // Set the newly created shape layer as the mask for the view's layer
    self.layer.mask = maskLayer;
    self.layer.shouldRasterize = YES;
}

@end

This works, but there is serious frame loss / lag when I pull up the pull-up menu (Note that the menu overlaps, appearing on top of the graph). When I take away the rounded corners, the menu pulls up beautifully. From what I gather, I need a way to round the corners by directly modifying the view, not by using a mask layer. Does anyone know how I could pull this off or have another possible solution? Any help greatly appreciated

2

2 Answers

4
votes

From what I gather, I need a way to round the corners by directly modifying the view, not by using a mask layer. Does anyone know how I could pull this off or have another possible solution?

The usual way is to get the view's layer and set the cornerRadius property:

myView.layer.cornerRadius = 10.0;

That way there's no need for a mask layer or a bezier path. In the context of your method, it'd be:

-(void)setRoundedCorners:(UIRectCorner)corners radius:(CGFloat)radius
{
    self.layer.cornerRadius = radius;
}

Update: Sorry -- I missed this part:

The design calls for these bars to have rounded corners on the top left and top right corner, but square corners on the bottom left and bottom right

If you only want some of the corners rounded, you can't do that by setting the layer's cornerRadius property. Two approaches you could take:

  • Create a bezier path with two corners rounded and two square, and then fill it. No need for a mask layer to do that.

  • Use a resizable image. See UIImage's -resizableImageWithCapInsets: and -resizableImageWithCapInsets:resizingMode: methods. There are even some methods for animating reizable images, so you could easily have your bars grow to the right length.

1
votes

Try setting shouldRasterize on your layers. Should help.