Анимация удаления аннотаций

У меня есть карта и набор аннотаций, каждая из которых имеет родительское свойство. В настоящее время, когда я добавляю аннотации, я реализую метод didAddAnnotationViews для анимации этих аннотаций, чтобы они выглядели как исходящие из координаты своего родителя. Есть ли способ сделать это во время удаления аннотаций? Когда я удаляю аннотацию с карты, я хочу, чтобы она анимировалась в своей родительской координате, и, насколько мне известно, для didAddAnnotationViews нет эквивалента при удалении аннотации.


person benwad    schedule 19.12.2011    source источник


Ответы (2)


Анимируйте аннотацию до ее удаления с карты и выполните удаление после завершения анимации. Код может выглядеть так:

- (void) removeMyAnnotation:(MyAnnotation*)annotation{
   [UIView animateWithDuration:1.0f
                    animations:^(void){
                         annotation.coordinate = annotation.parentAnnotation.coordinate;
                    }
                    completion:^(BOOL finished)completion{
                        [mapView removeAnnotation:annotation];
                    }
}
person Vladimir    schedule 19.12.2011
comment
Спасибо - еще одна вещь, есть ли способ получить доступ к соответствующему MKAnnotationView аннотации, чтобы я мог перемещать его таким образом? Потому что мой класс аннотации вычисляет свою координату динамически, поэтому ее нельзя установить (если только я не добавлю множество функций для установки пользовательских координат, чего я бы предпочел избежать). - person benwad; 20.12.2011
comment
@benwad, вы можете получить его с помощью метода viewForAnnotation в MKMapView, хотя он не гарантирует, что он всегда будет возвращать фактический вид (например, он может вернуть nil, если аннотация не видна) - person Vladimir; 20.12.2011
comment
@indiekiduk, проверьте вопрос - в его условиях каждая аннотация имеет свойство parentAnnotation - person Vladimir; 11.07.2013
comment
привет, Владимир, мне нужна твоя помощь, посмотри на этот вопрос stackoverflow.com/q/19268080/1468406, пожалуйста, помогите, если у вас есть идеи . - person pratik bhiyani; 15.10.2013

Вы должны НЕ откладывать вызов removeAnnotation, как в ответе @Vladimir, потому что состояние MKMapView может быть изменено во время анимации.

К моменту вызова removeAnnotation из блока завершения анимации другие аннотации могут быть добавлены/удалены из MapView, поэтому в некоторых случаях вы можете удалить неправильный набор аннотаций.

Я написал эту категорию для MKMapView, которую вы можете использовать для безопасного удаления анимированных аннотаций:

@interface MKMapView (RemoveAnnotationWithAnimation)

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;
- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated;

@end

И файл .m:

@implementation MKMapView (RemoveAnnotationWithAnimation)

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated
{
    [self removeAnnotations:@[annotation] animated:animated];
}

- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated
{
    if (animated) {
        NSSet * visibleAnnotations = [self annotationsInMapRect:self.visibleMapRect];
        NSMutableArray * annotationsToRemoveWithAnimation = [NSMutableArray array];
        for (id<MKAnnotation> annotation in annotations) {
            if ([visibleAnnotations containsObject:annotation]) {
                [annotationsToRemoveWithAnimation addObject:annotation];
            }
        }
        NSMutableArray * snapshotViews = [NSMutableArray array];
        for (id<MKAnnotation> annotation in annotationsToRemoveWithAnimation) {
            UIView * annotationView = [self viewForAnnotation:annotation];
            if (annotationView) {
                UIView * snapshotView = [annotationView snapshotViewAfterScreenUpdates:NO];
                snapshotView.frame = annotationView.frame;
                [snapshotViews addObject:snapshotView];
                [[annotationView superview] insertSubview:snapshotView aboveSubview:annotationView];
            }
        }
        [UIView animateWithDuration:0.5
                         animations:^{
                             for (UIView * snapshotView in snapshotViews) {
                                 // Change the way views are animated if you want
                                 CGRect frame = snapshotView.frame;
                                 frame.origin.y = -frame.size.height;
                                 snapshotView.frame = frame;
                             }
                         }
                         completion:^(BOOL finished) {
                             for (UIView * snapshotView in snapshotViews) {
                                 [snapshotView removeFromSuperview];
                             }
                         }];
    }
    [self removeAnnotations:annotations];
}

@end
person nalexn    schedule 15.02.2015
comment
Я реализовал это решение для исчезновения моих аннотаций. Это не работает при панорамировании карты, когда виды снимков исчезают, так как они остаются на месте, пока карта перемещается. Выглядит довольно странно. - person duncanc4; 13.01.2016
comment
Прочитав ваш комментарий и подумав о решении @Vladimir, я не понимаю, как добавление или удаление различных аннотаций во время анимации влияет на возможность удаления конкретной аннотации при выполнении блока завершения. Блок захватывает указатель, поэтому у него есть точная аннотация, которую нужно удалить. Единственная проблема, которую я мог видеть, заключается в том, что какой-то другой код удалил точную аннотацию, которая анимировалась. Я не уверен, что делает MKMapView, если у него нет аннотации, которую вы пытаетесь удалить. - person duncanc4; 13.01.2016
comment
@duncanc4 Проблема в том, что MKMapView повторно использует экземпляры представления аннотаций, как это делает UITableView со своими ячейками. Поэтому, если вы сохраните указатель на удаляемую аннотацию и прокрутите карту до другой группы аннотаций, вы можете удалить неправильную аннотацию при выполнении блока. - person nalexn; 13.01.2016
comment
Если вы сохраните MKAnnotationView, это произойдет, но как это произойдет, если вы сохраните MKAnnotation, поскольку MKMapView не использует повторно MKAnnotations? - person duncanc4; 13.01.2016
comment
Да, правильно. Помню, у меня были проблемы с решением Владимира, и мне пришлось придумать свое. Я не помню всех подробностей, к сожалению. В общем, я все же считаю, что обновление Презентации нужно делать одновременно с обновлением Модели. Когда время ограничено и вы откладываете обновление модели, остерегайтесь неожиданного состояния презентации. - person nalexn; 13.01.2016
comment
Это старая тема, но я все равно напишу. Объект аннотации — это любой объект, соответствующий протоколу MKAnnotation. Это объект модели, и он не используется повторно. Изменение координат объекта аннотации не должно вызывать проблем с повторным использованием вида. Если вы удалите аннотацию, карта будет проверять, есть ли у этой аннотации вид на экране, и удалять его, если да, и не изменять виды карты, если вид этой аннотации не отображается на экране. @duncanc4, привет еще одному DuncanC! Здесь мало Дунканов, но ты единственный другой Дункан, которого я видел! - person Duncan C; 20.05.2017