9

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 ...

}

それで、何かアイデアはありますか?前もって感謝します!

4

1 に答える 1

0

数か月前、このアニメーション化された MKCircleViewに出くわしました。git のデモもあります。だから私はあなたがそれを試してみるべきだと思います!sliderなどでニーズに合わせて微調整できるかもしれないので、チェックしてください。

これを提供してくれたyickhongにクレジットが送られますYHAnimatedCircleView

于 2013-07-12T16:20:21.363 に答える