refreshing mkannotation properties and refreshing the annotation

Asked
Viewd1079

3

I have a mkannotation located on a mapview which has a mkannotationview as well as a calloutview which when clicked goes to a child uiviewcontroller. I am updating some properties from the callout's uiviewcontroller, but after I'm finished I want to move the annotation's position on the map and change the annotation title and subtitle. How can I easily do this from the callout's uiviewcontoller? What's the most elegant way to handle this? A code sample would be great if anyone has any.

Thanks

4 ответов

1

Полностью удалите аннотацию с карты, обновите ее и снова добавьте на карту. Это гарантирует, что карта заметит, что расположение аннотаций изменилось.

1

Хотя вы можете удалить и снова добавить аннотацию, как предлагает @Caleb, другой вариант - обновить свойство coordinate непосредственно в аннотации, которую вы хотите переместить.

Обратите внимание, что это будет работать только в том случае, если ваш класс аннотации реализует setCoordinate, что можно легко сделать, объявив coordinate как assign (как это делает встроенный класс MKPointAnnotation) вместо readonly. В представлении карты изменение будет отображаться через KVO и переместить аннотацию.

Чтобы дочерний контроллер представления сообщал контроллеру представления карты, какую аннотацию следует изменить и каковы новые координаты, я рекомендую использовать протокол делегат +, как предлагает другой ответ.

0

Самый простой способ - не делать этого из дочернего контроллера представления. Возможно, ваши потребности отличаются от того, что я понял из вопроса, но на первый взгляд я бы сделал что-то вроде этого:

В шапке:

 @interface YourController
{
    ...
    MKAnnotation *_latestDetailViewed;
}

... 
@property(nonatomic, retain) MKAnnotation *latestDetailViewed;

@end
 

Затем в .m что-то вроде

 @implementation YourController

... 
@synthesize latestDetailViewed = _latestDetailViewed;

...
-(void) dealloc
{
    ...
    self.latestDetailViewed = nil;
    [super dealloc];
}

-(void) whereverYouLaunchYourDetailScreenFrom:(MKAnnotation*)detailAnnotation
{
    self.latestDetailViewed = detailAnnotation;
    // then create/push your view controller
}

-(void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if(_latestDetailViewed)
    {
        // Do whatever you want to the annotation here
        self.latestDetailViewed = nil;
    }
}
 

Таким образом, ваши изменения будут внесены, когда вы вернетесь к карте. Если вы действительно запускаете подробное представление только для одной аннотации за раз и всегда возвращаетесь к карте между ними, тогда это должно работать, не заставляя вас писать протокол делегата или отключать NSNotifications.

Если я неправильно понимаю вашу ситуацию, дайте мне знать, и я дам вам другой ответ :)

1

Я бы создал протокол, скажем, MapCallBackDelegate, для обработки того, что вы хотите делать. Это позволяет избежать сильно связанного кода. Поместите это в файл заголовка представления аннотации карты

 @protocol MapCallBackDelegate
    -(void)updateAnnotation:(id)whatEverParamsYouWant;
@end
 

Затем заставьте ваш Map View реализовать этот протокол. Когда вы создаете вид аннотации карты, присвойте ему свойство

 @property (nonatomic, retain) id<MapCallBackDelegate> callbackDelegate;
 

И когда вы добавляете его на свою карту, установите для этого свойства значение self

 myMapAnnotationView.callbackDelegate = self;
 

поэтому, когда вы хотите изменить заголовок / подзаголовок / позицию, вы просто вызываете это сообщение в callbkacDelegate.

Это элегантно, так как сокращает тесно связанный код, позволяет другим объектам реализовать тот же протокол для повторного использования кода позже и способствует скрытию информации в вашем MapAnnotationView.