8
votes

I'm building a custom UITableView with each of the cells containing a piece of text and a MKMapView. I want the map "icon" view in the cell to have rounded corners and this seems to be an issue.

I'm using custom drawing both for my UITableViewCell and my MapIcon (custom map view) that I add to my UITableViewCell.

MapIcon is a subclass of MKMapView and the drawing method looks as follows:

-(void)drawRect:(CGRect)rect {

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, strokeWidth);
CGContextSetStrokeColorWithColor(context,self.strokeColor.CGColor);
CGContextSetFillColorWithColor(context, self.rectColor.CGColor);

CGFloat radius = arcRadius;

CGFloat Xmin = CGRectGetMinX(rect);
CGFloat Xmid = CGRectGetMidX(rect);
CGFloat Xmax = CGRectGetMaxX(rect);

CGFloat Ymin = CGRectGetMinY(rect);
CGFloat Ymid = CGRectGetMidY(rect);
CGFloat Ymax = CGRectGetMaxY(rect);   

CGContextBeginPath(context); CGContextMoveToPoint(context, Xmin, Ymid); CGContextAddArcToPoint(context, Xmin, Ymin, Xmid, Ymin, radius); CGContextAddArcToPoint(context, Xmax, Ymin, Xmax, Ymid, radius); CGContextAddArcToPoint(context, Xmax, Ymax, Xmid, Ymax, radius); CGContextAddArcToPoint(context, Xmin, Ymax, Xmin, Ymid, radius); CGContextClosePath(context);

CGContextDrawPath(context, kCGPathFillStroke);

CGContextClip(context); CGContextEndTransparencyLayer(context); }

And the maps do not get the corners rouned, as can be seen in the below screenshot:

alt text http://img190.imageshack.us/img190/948/picture1vmk.png

If however I change the MapIcon to subclass from UIView and use the same custom drawing methods, the view gets clipped perfectly, image below:

alt text http://img503.imageshack.us/img503/6269/picture2xkq.png

Is it wrong for me to subclass MKMapView in such a way and expect it to clip? Any other any of rounding these corners?

Cheers, Kaspa

4
Did you find that putting a mapview here crashes when it exits and re-enteres the view?ingh.am

4 Answers

43
votes

The easiest way to make round corners:

#import <QuartzCore/QuartzCore.h>
myMapView.layer.cornerRadius = 10.0;
3
votes

Just a small correction as the import statement is misspelt in digdog's answer.

Should be

#import <QuartzCore/QuartzCore.h>
myMapView.layer.cornerRadius = 10.0;
1
votes

Take a look at the last paragraph of the Overview section in the MKMapView class reference:

Although you should not subclass the MKMapView class itself,...

I think that pretty well answers your question of whether you should subclass it. One thing you could do is put another view on top of the MKMapView that looks like the background to round the corners. If you need it to be of arbitrary size, you can try the strechableImage method on UIImage.

0
votes

It's also fairly easy to round specific corners if you need. For example, when the map is located at the top of a NSTableViewCell inside a grouped NSTableView

Slightly modified from ACEToolKit:

#import <QuartzCore/QuartzCore.h>
- (void)awakeFromNib {
CGRect rect = self.bounds;
float radius = 10.f;

// Create the path
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect
                                               byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
                                                     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.mapView.layer.mask = maskLayer;
}