2013-07-10 15 views
7

Wie kann ich beim Anpassen eines NSSliders eine reibungslose Größenanpassung eines MKCircleView auf einem UIMapView erreichen? Apple hat es geschafft, es in der Finden Sie meine Freunde App bei der Erstellung von Geofences (http://reviewznow.com/wp-content/uploads/2013/03/find-my-friends-location-alerts-01.jpg), so dass ich denke, es ist in irgendeiner Weise möglich. Bisher habe ich die folgenden Lösungen ausprobiert, aber mit einem sehr „flickery“ Ergebnis:Glatte Größenanpassung von MKCircle

Erster Versuch

Ich habe eine neue MKCircleView mit einem aktualisierten Radius und unmittelbar nach dem einen zu entfernen, die war (wie vorgeschlagen hier MKOverlay not resizing smoothly), wenn der Schieberegler Wert geändert. Ich habe es auch andersherum versucht: zuerst das Overlay entfernen und dann ein neues hinzufügen, aber mit dem gleichen "Flicker" -Ergebnis.

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

Zweiter Versuch

in der so verbunden beantworten, schlägt er vor, dass NSOperation verwendet werden könnte, um „Ihnen helfen, die MKCircle Objekte schneller erstellen“ und wodurch die glattere Ändern der Größe der obigen Verfahren unter Verwendung Zugabe/Überlagerungen entfernen, wenn die Folie den Wert ändert. Ich habe eine Implementierung gemacht, bei der ich einen neuen Thread starte, wenn sich der Slider ändert. In jedem Thread entferne ich alle alten Overlays und füge ein neues mit dem aktualisierten Maßstab hinzu. Vielleicht hat er eine andere Art von Implementierung im Sinn, denn so wie ich es gemacht habe, bekomme ich immer noch das gleiche Flimmern, wenn ich den Schieberegler ändere.

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

Die Methode, die ich jeden Thread läuft:

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

Dritter Versuch

Ich habe auch versucht, meine eigene Unterklasse von MKOverlayView implementieren, die sich auf seiner Skala Eigenschaft zeichnet basiert. Immer wenn der Slider sich ändert, rufe ich setNeedsDisplay auf und lasse es sich neu zeichnen, aber ich bekomme das gleiche Flimmern.

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

Und in meiner benutzerdefinierten Overlay-Ansicht I drawMapRect implementieren: zoomScale: InContext: (CGContextRef) Kontext wie diese

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

} 

Also, haben Sie irgendwelche Ideen? Danke im Voraus!

+0

Ich kämpfe mit diesem auch yickhong, wie hast du das gemacht? –

Antwort

0

Vor ein paar Monaten stolperte ich über this animated MKCircleView. Es hat auch eine Demo auf Git. Also ich denke du solltest es ausprobieren! Check it out, wie Sie vielleicht in der Lage sein, es mit einem slider usw.

Credits auf Ihre Bedürfnisse zu optimieren gehen für die Bereitstellung dieser YHAnimatedCircleView