NSSlider を調整するときに、UIMapView で MKCircleView のサイズをスムーズに変更するにはどうすればよいですか? Apple は、ジオフェンス ( http://reviewznow.com/wp-content/uploads/2013/03/find-my-friends-location-alerts-01.jpg )を作成するときに、 Find my friendsアプリでそれを行うことができたので、ある程度は可能だと思います。これまでのところ、次の解決策を試しましたが、非常に「ちらつき」のある結果になりました。
最初の試み
更新された半径を持つ新しい MKCircleView を追加し、スライダーの値が変更されたときに ( MKOverlay がスムーズにサイズ変更されないことを示唆しているように) あったものを削除した直後に追加しました。逆の方法も試しました。最初にオーバーレイを削除してから新しいオーバーレイを追加しましたが、同じ「ちらつき」の結果が得られました。
- (void)sliderChanged:(UISlider*)sender
{
double radius = (sender.value * 100);
[self addCircleWithRadius:radius];
[mapView removeOverlays:[self.mapView.overlays firstObject]];
}
2 回目の試行
リンクされた 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];
}
3 回目の試行
また、scale プロパティに基づいて自身を描画する MKOverlayView の独自のサブクラスを実装してみました。スライダーが変更されるたびに、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 ...
}
それで、何かアイデアはありますか?前もって感謝します!