9

调整 NSSlider 时,如何在 UIMapView 上平滑调整 MKCircleView 的大小?Apple在创建地理围栏(http://reviewznow.com/wp-content/uploads/2013/03/find-my-friends-location-alerts-01.jpg )时已设法在“查找我的朋友”应用程序中做到这一点,所以我想这在某种程度上是可能的。到目前为止,我已经尝试了以下解决方案,但结果非常“闪烁”:

第一次尝试

我添加了一个新的 MKCircleView ,其半径已更新,并在删除滑块更改值时立即删除(如此处建议的MKOverlay not resizing )。我也尝试了另一种方法:首先删除覆盖然后添加一个新的,但具有相同的“闪烁”结果。

- (void)sliderChanged:(UISlider*)sender
{
    double radius = (sender.value * 100);
    [self addCircleWithRadius:radius];
    [mapView removeOverlays:[self.mapView.overlays firstObject]];
}

第二次尝试

在链接的 SO 答案中,他建议 NSOperation 可用于“帮助您更快地创建 MKCircle 对象”,从而在幻灯片更改值时使用上述添加/删除叠加层的方法使调整大小更平滑。我做了一个实现,只要滑块发生变化,我就会启动一个新线程。在每个线程中,我删除所有旧的覆盖并添加一个具有更新比例的新覆盖。也许他有一些其他的实现方式,因为我这样做的方式在更改滑块时仍然会出现相同的闪烁。

- (void)sliderChanged:(UISlider*)sender
{
     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                             selector:@selector(updateOverlayWithScale:)
                                                                               object:[NSNumber numberWithFloat:sender.scale]];
     [self.queue addOperation:operation];
}

在每个线程中运行的方法:

- (void)updateOverlayWithScale:(NSNumber *)scale
{
    MKCircle *circle = [MKCircle circleWithCenterCoordinate:self.currentMapPin.coordinate
                                                     radius:100*[scale floatValue]];


    [self.mapView performSelectorOnMainThread:@selector(removeOverlays:) withObject:self.mapView.overlays waitUntilDone:NO];
    [self.mapView performSelectorOnMainThread:@selector(addOverlay:) withObject:circle waitUntilDone:NO];
}

第三次尝试

我还尝试实现我自己的 MKOverlayView 子类,它根据它的 scale 属性绘制自己。每当滑块发生变化时,我都会调用 setNeedsDisplay 并让它自己重绘,但我会得到相同的闪烁。

- (void)sliderChanged:(UISlider*)sender
{
     self.currentOverlayView.scale = sender.scale
     [self.currentOverlayView setNeedsDisplay];
}

在我的自定义叠加视图中,我像这样实现 drawMapRect:zoomScale:inContext:(CGContextRef)context

- (void)drawMapRect:(MKMapRect)mapRect
          zoomScale:(MKZoomScale)zoomScale
          inContext:(CGContextRef)context
{
     double radius = [(MKCircle *)[self overlay] radius];
     radius *= self.scale;

     // ... Create a rect using the updated radius and draw a circle inside it using CGContextAddEllipseInRect ...

}

那么,你有什么想法吗?提前致谢!

4

1 回答 1

0

几个月前,我偶然发现了这个动画 MKCircleView。它还有一个关于 git 的演示。所以我想你应该试一试!检查一下,因为您可能可以使用slider等来调整它以满足您的需求。

学分去 yickhong 提供这个YHAnimatedCircleView

于 2013-07-12T16:20:21.363 回答