Draw a circle with a hole using MKOverlayRenderer does not work

I would like to draw a circle with a hole (like a donut) on the map. my code is here.

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CG    ContextRef)context {

WPCircleOverlay * circleOverlay = self.overlay;

CGPoint centerPoint = [self pointForMapPoint:MKMapPointForCoordinate(circleOverlay.coordinate)];

CGFloat innerRadius = MKMapPointsPerMeterAtLatitude(circleOverlay.coordinate.latitude) * circleOverlay.innerRadius;
CGFloat outerRadius = MKMapPointsPerMeterAtLatitude(circleOverlay.coordinate.latitude) * circleOverlay.outerRadius;
CGMutablePathRef path = CGPathCreateMutable();

//CGPathMoveToPoint(path, ...);
CGPathAddArc(path, NULL, centerPoint.x, centerPoint.y, outerRadius, 0, 2 * M_PI, true);
CGPathCloseSubpath(path);

// Add the inner arc to the path (later used to substract the inner area)
CGPathAddArc(path, NULL, centerPoint.x, centerPoint.y, innerRadius, 0, 2 * M_PI, true);
CGPathCloseSubpath(path);

// Add the path to the context
CGContextAddPath(context, path);

CGContextSetFillColorWithColor(context, self.fillColor.CGColor);
CGContextEOFillPath(context);

CGPathRelease(path);

It works well in the simulator, but on the device it is not.

On the device, the outer circle is filled with color, and the inner circle is not cropped. How can I change my code to work well on the device?

+4
source share
1 answer

I fixed it using the CGContextAddEllipseInRect method instead of CGContextAddArc.

WPCircleOverlay * circleOverlay = self.overlay;

CGRect rectForMapRect = [self rectForMapRect:mapRect];
CGPoint centerPoint = [self pointForMapPoint:MKMapPointForCoordinate(circleOverlay.coordinate)];

CGFloat innerRadius = MKMapPointsPerMeterAtLatitude(circleOverlay.coordinate.latitude) * circleOverlay.innerRadius;
CGFloat outerRadius = MKMapPointsPerMeterAtLatitude(circleOverlay.coordinate.latitude) * circleOverlay.outerRadius;

CGRect innerRect = CGRectMake(centerPoint.x - innerRadius, centerPoint.y - innerRadius, innerRadius * 2.0, innerRadius * 2.0);
CGRect outerRect = CGRectMake(centerPoint.x - outerRadius, centerPoint.y - outerRadius, outerRadius * 2.0, outerRadius * 2.0);

if (CGRectIntersectsRect(rectForMapRect, outerRect)) {

    CGContextAddRect(context, rectForMapRect);

    CGContextSaveGState(context);
    CGContextClip(context);

    CGContextAddEllipseInRect(context, outerRect);
    CGContextAddEllipseInRect(context, innerRect);

    CGContextSaveGState(context);
    CGContextEOClip(context);

    UIColor * color = [self.fillColor copy];
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, outerRect);

    CGContextRestoreGState(context);
    CGContextRestoreGState(context);

    UIGraphicsPopContext();
}
+2
source

Source: https://habr.com/ru/post/1527811/


All Articles