2013-07-10 3 views
7

Как добиться плавного изменения размера MKCircleView в UIMapView при настройке NSSlider? Apple удалось сделать это в Найти друзей приложение при создании geofences (http://reviewznow.com/wp-content/uploads/2013/03/find-my-friends-location-alerts-01.jpg), так что, я думаю, это возможно в некотором роде. До сих пор я попытался следующие решения, но в результате очень «flickery»:Плавное изменение размера MKCircle

Первая попытка

Я добавил новый MKCircleView с обновленным радиусом и сразу после удаления одного, который был (как предлагаемый здесь MKOverlay not resizing smoothly), когда ползунок изменил значение. Я также пробовал наоборот: сначала удаляю оверлей, а затем добавляю новый, но с тем же результатом «мерцания».

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

Вторая попытка

В связанный 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]; 
} 

Метод, который работает каждый поток I:

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

Третья попытка

Я также попытался реализации мой собственный подкласс MKOverlayView, который привлекает сама основана на его шкале ценностей. Всякий раз, когда изменяется слайдер, я вызываю setNeedsDisplay и позволяю ему перерисовывать себя, но я получаю такое же мерцание.

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

И в мой пользовательский вид наложения я реализую 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 ... 

} 

Итак, у вас есть какие-нибудь идеи? Заранее спасибо!

+0

я борюсь с этим тоже, как ты это сделал? –

ответ

0

Несколько месяцев назад я наткнулся на this animated MKCircleView. В нем также есть демо-версия git. Так что, я думаю, вы должны отдать это! Проверьте это, как вы могли бы быть в состоянии настроить его под свои нужды с slider и т.д.

Кредиты идут на yickhong за предоставление этой YHAnimatedCircleView