为什么MKOverlayRenderer上的drawRect变慢

对于一个应用程序,我必须在MKMapView上放置一个MKCircle注解。 但是,圈子需要移动/resize。 我知道这已经被问到了,例如在MKMapView中移动MKCircle,其中删除/添加注释被build议获得该行为。

不过,我认为绘图速度很慢,就像这篇文章中的用户: MKCircle的平滑resize 。 由于现在有这个问题的答案,这个问题似乎使用YHAnimatedCircleView 。 我的意思是说,当我使用UISlider来改变圆的半径时,重绘是sl and不驯的,我也可以注意到用来绘制的瓷砖。

我创build了一个小testing代码,覆盖子类MKOverlayRenderer的drawMapRect 。 代码如下:

 -(void) drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { MKCircle* circleOverlay = (MKCircle*)self.overlay; CLLocationCoordinate2D point = circleOverlay.coordinate; CGPoint locationPoint = [self pointForMapPoint:MKMapPointForCoordinate(point)]; CGFloat radius = MKMapPointsPerMeterAtLatitude(circleOverlay.coordinate.latitude) * circleOverlay.radius; CGRect circleRect = CGRectMake(locationPoint.x - radius, locationPoint.y - radius, radius * 2.0, radius * 2.0); CGContextSaveGState(context); CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor); CGContextFillEllipseInRect(context, circleRect); CGContextRestoreGState(context); } 

当我移动UISlider时,旧的注释被移除,放置不同半径的新MKCircle ,并调用drawMapRect方法。

但是,即使是这个小例子,在调整圆圈大小的时候也会显得草率。

问题:

  1. 上面的例子是完全正确的,还是我在绘画上做错了?
  2. 如果这个例子是正确的,那么为什么在重新调整它的大小时,重新绘制这个圆是如此缓慢/草率?

我有一个类似的问题,在MKMapView上绘制覆盖图,我的问题是移动我绘制的与地图有关的圆。 这导致地图移动滞后的问题,与地图上的移动相比,看起来好像圈子在地图上滑动,而不是固定在地图上。

我的解决scheme是使用CADisplayLink为了同步MKMapView的绘图和我添加到它的任何视图。 我相信这将与你的原始实施改变使用UISlider的圆的半径,但是没有执行,我不能彻底地testing这个。

一个代码示例如下所示:

 - (void)viewDidLoad { self.mapUpdateLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateMapView)]; [self.mapUpdateLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; } - (void)updateMapView { CGPoint centerPoint = [self.mapView convertCoordinate:self.circleView.centerCoordinate toPointToView:self.view]; if (!isnan(centerPoint.x) && !isnan(centerPoint.y)) { self.circleView.center = centerPoint; } } 

我希望这可以帮助你解决你的问题。

据我所知在MKMapView的drawRect是非常缓慢的。 (作为CCHMapClusterController一个好奇心的人也发现了 )

我会做的是生成一个UIImage,而不是做绘制矩形:

 UIImage *circle; CGRect circleRect = CGRectMake(locationPoint.x - radius, locationPoint.y - radius, radius * 2.0, radius * 2.0); UIGraphicsBeginImageContextWithOptions(CGSizeMake(radius * 2.0, radius * 2.0), NO, 0.0f); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSaveGState(ctx); CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor); CGContextFillEllipseInRect(context, circleRect); CGContextRestoreGState(ctx); circle = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

您可以在AnnotationView中的layoutSubViews中生成该图像(很像链接显示:))。 AnnotationView可以有一个半径,UISlider会改变半径。 在您的setRadius属性中,您可以调用setNeedsLayout