Płynna zmiana rozmiaru MKCircle

Jak uzyskać płynną zmianę rozmiaru MKCircleView na UIMapView podczas dostosowywania NSSlider? Apple udało się to zrobić wZnajdź moich przyjaciół aplikacja podczas tworzenia geofence (http://reviewznow.com/wp-content/uploads/2013/03/find-my-friends-location-alerts-01.jpg), więc myślę, że jest to możliwe w jakiś sposób. Do tej pory wypróbowałem następujące rozwiązania, ale z bardzo „migotliwym” wynikiem:

Pierwsze podejscie

Dodałem nowy MKCircleView ze zaktualizowanym promieniem i natychmiast po usunięciu tego, który był (jak sugerowano tutajMKOverlay nie zmienia płynnie rozmiaru), gdy suwak zmienił wartość. Próbowałem też odwrotnie: najpierw usunąłem nakładkę, potem dodałem nową, ale z tym samym „migotliwym” wynikiem.

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

Drugie podejście

W połączonej odpowiedzi SO sugeruje, że NSOperation może być użyty do „pomocy w szybszym tworzeniu obiektów MKCircle”, a tym samym do płynniejszej zmiany rozmiaru przy użyciu powyższej metody dodawania / usuwania nakładek, gdy slajdy zmieniają wartość. Zrobiłem implementację, w której uruchamiam nowy wątek, gdy zmienia się suwak. W każdym wątku usuwam wszystkie stare nakładki i dodajemy nowe z zaktualizowaną skalą. Być może ma on na myśli inny rodzaj implementacji, ponieważ sposób, w jaki to zrobiłem, wciąż zmienia się w ten sam sposób podczas zmiany suwaka.

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

Metoda, która uruchamia każdy wątek:

- (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];
}

Trzecia próba

Próbowałem również zaimplementować własną podklasę MKOverlayView, która rysuje się na podstawie jej właściwości skali. Ilekroć zmienia się suwak, wywołuję setNeedsDisplay i pozwalam mu się przerysowywać, ale mam takie samo migotanie.

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

W moim niestandardowym widoku nakładki implementuję kontekst drawMapRect: zoomScale: inContext: (CGContextRef)

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

}

Czy masz jakieś pomysły? Z góry dziękuję!

questionAnswers(1)

yourAnswerToTheQuestion