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ę!