我发现了如何围绕地图注释绘制圆圈。 我是这样做的:
MKCircle *circle = [MKCircle circleWithCenterCoordinate:theCoordinate radius:15000];
[myMap addOverlay:circle];
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
{
MKCircleView *circleView = [[MKCircleView alloc] initWithOverlay:overlay];
circleView.fillColor =[UIColor redColor];
return circleView;
}
它工作正常,但我想绘制一个圆圈,其填充颜色不是这样的实体:
答案 0 :(得分:10)
使用MKCircleRenderer答案iOS 7 ...
您应该继承MKCircleRenderer,并覆盖fillPath:inContext
方法,类似于此问题的已接受答案。 e.g。
@implementation MKGradientCircleRenderer
- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context
{
CGRect rect = CGPathGetBoundingBox(path);
CGContextAddPath(context, path);
CGContextClip(context);
CGFloat gradientLocations[2] = {0.6f, 1.0f};
// Start color white with 0.25 alpha,
// End color green with 0.25 alpha
CGFloat gradientColors[8] = {1.0f, 1.0f, 1.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.25f};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);
CGColorSpaceRelease(colorSpace);
CGPoint gradientCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
CGFloat gradientRadius = MIN(rect.size.width, rect.size.height) / 2;
CGContextDrawRadialGradient(context, gradient, gradientCenter, 0, gradientCenter, gradientRadius, kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient);
}
然后在你的MKMapView委托中,实现以下方法......
-(MKOverlayRenderer *)mapView:(MKMapView*)mapView rendererForOverlay:(id<MKOverlay>)overlay {
MKCircle * circle = (MKCircle *)overlay;
MKGradientCircleRenderer * renderer = [[MKGradientCircleRenderer alloc] initWithCircle:circle];
return renderer;
}
这将允许您实现相同的效果,但使用iOS 7中提供的新方法。
答案 1 :(得分:6)
要使用渐变绘制圆,您必须提供自己的注释视图类,因为现有的都不支持。你可以做的是你可以覆盖- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context
的子类中的方法MKCircleView
。以下是一些代码(非优化,带有硬编码填充参数),可帮助您入门:
@interface TWOGradientCircleView : MKCircleView
@end
@implementation TWOGradientCircleView
- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context
{
CGRect rect = CGPathGetBoundingBox(path);
CGContextAddPath(context, path);
CGContextClip(context);
CGFloat gradientLocations[2] = {0.6f, 1.0f};
// Start color white with 0.25 alpha,
// End color green with 0.25 alpha
CGFloat gradientColors[8] = {1.0f, 1.0f, 1.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.25f};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);
CGColorSpaceRelease(colorSpace);
CGPoint gradientCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
CGFloat gradientRadius = MIN(rect.size.width, rect.size.height) / 2;
CGContextDrawRadialGradient(context, gradient, gradientCenter, 0, gradientCenter, gradientRadius, kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient);
}
要使用它,只需将MKCircleView
替换为TWOGradientCircleView
:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
{
MKCircleView *circleView = [[TWOGradientCircleView alloc] initWithOverlay:overlay];
return circleView;
}
如果您想使用图像而不是绘制渐变,可以使用图像绘制替换上面的渐变图。由于放大会使图像模糊,您应该禁用缩放,或者像Apple在WWDC10的会话中演示的那样平铺图像(有关其示例代码的存储库,请参阅here)。使用图案图像设置UIColor
对半径为15000不起作用(除非您使用非常非常大的图像;)。
答案 2 :(得分:3)
您是否尝试将填充颜色设置为使用[UIColor colorWithPatternImage:]
创建的颜色?
答案 3 :(得分:3)
为了在Swift 2.0(iOS7 +)中实现解决方案,我使用了以下解决方案
import Foundation
import MapKit
class TWOGradientCircleRenderer: MKCircleRenderer {
override func fillPath(path: CGPath, inContext context: CGContext) {
let rect:CGRect = CGPathGetBoundingBox(path)
CGContextAddPath(context, path);
CGContextClip(context);
let gradientLocations: [CGFloat] = [0.6, 1.0];
let gradientColors: [CGFloat] = [1.0, 1.0, 1.0, 0.25, 0.0, 1.0, 0.0, 0.25];
let colorSpace = CGColorSpaceCreateDeviceRGB();
let gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);
let gradientCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
let gradientRadius = min(rect.size.width, rect.size.height) / 2;
CGContextDrawRadialGradient(context, gradient, gradientCenter, 0, gradientCenter, gradientRadius, .DrawsAfterEndLocation);
}
}
在您的MKMapViewDelegate中,您需要添加
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKCircle {
let circleRenderer = TWOGradientCircleRenderer(overlay: overlay)
return circleRenderer
} else {
return MKOverlayRenderer()
}
}
答案 4 :(得分:2)
这个答案适用于Swift 3.0 / iOS 10。
class CircleRenderer: MKCircleRenderer {
override func fillPath(_ path: CGPath, in context: CGContext) {
let rect: CGRect = path.boundingBox
context.addPath(path)
context.clip()
let gradientLocations: [CGFloat] = [0.6, 1.0]
let gradientColors: [CGFloat] = [1.0, 1.0, 1.0, 0.25, 0.0, 1.0, 0.0, 0.25]
let colorSpace = CGColorSpaceCreateDeviceRGB()
guard let gradient = CGGradient(colorSpace: colorSpace, colorComponents: gradientColors, locations: gradientLocations, count: 2) else { return }
let gradientCenter = CGPoint(x: rect.midX, y: rect.midY)
let gradientRadius = min(rect.size.width, rect.size.height) / 2
context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: 0, endCenter: gradientCenter, endRadius: gradientRadius, options: .drawsAfterEndLocation)
}
}
覆盖委托方法:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let circleRenderer = CircleRenderer(overlay: overlay)
return circleRenderer
}
这方面的一个例子:
答案 5 :(得分:1)
**仅更新答案:
在IOS 7中,fillPath:inContext已弃用为MKCircleView。请尝试使用MKCircleRenderer。