MKMapView refresh after pin moves
Asked Answered
H

7

9

A custom AnnotationView is updated with new coordinates. But the problem is that it visually updates only after some manipulations with MKMapView, e.g. zooming or moving. What should I do to manually update visual position on a map?

PS. I've tried to change region to current map's region. But it does change zoom. It's strange.

[mapView setRegion:[mapView region] animated:YES];
Heist answered 27/7, 2009 at 19:52 Comment(1)
Kindly see my answer at the following link: https://mcmap.net/q/401976/-how-to-move-a-mkannotation-without-adding-removing-it-from-the-mapLatif
H
19

I am a little shoked after hours of research. The answer is just:

[mapView setCenterCoordinate:mapView.region.center animated:NO];

Do not ask me why, but it updates a mapview and it's what i was need.

Heist answered 30/7, 2009 at 8:37 Comment(1)
UPD: it does not help with SDK 3.1. Still in research.Heist
E
13

MKMapView observes the coordinate property of annotations via KVO. You simply need to observe proper KVO protocol and send the annotation willChangeValueForKey: and didChangeValueForKey: with keypath of @"coordinate" before and after you update the coordinates.

Likewise title and subtitle are also observed by MKMapView. so if you update those and want the value in the callout to change automatically without any effort on your part, just do the same: call willChangeValueForKey: and didChangeValueForKey:

Elimination answered 30/7, 2010 at 13:26 Comment(1)
While the setCenterCoordinate:animated: works, the KVO way here also works and is definitely more appropriate and allows the MKMapView to coordinate updates from multiple observations better.Preponderance
I
9

if your adding your annoations from a thread it wont work. i had the same problem and just wrapping my function that was adding the annotations with the following worked

[self performSelectorOnMainThread:@selector(addCameraIconOnMain:) obj waitUntilDone:true];  

-(void) addCameraIconOnMain:(myobjecttype*)obj
{
    // this isnt the entire function, customize for your own purpose.....
    [mapView addAnnotation:annotation];
}
Interregnum answered 19/11, 2010 at 1:12 Comment(0)
T
2

The answer here is NOT to refresh the MapView or the Annotation!

the coordinate property of MKAnnotation has KVO on it. If you just add the id pointer, of the object you want on the map, to the mapview and update the coordinate property with a new location, MKMapView will do the rest for you.

As close as you can get to a free lunch!

Tiffany answered 7/9, 2010 at 20:44 Comment(0)
L
0

I solved this error with an asynchronous call, at least 0.5 delay.

e.g.: [self performSelector:@selector(redrawPins) withObject:nil afterDelay:0.5];

Where "redrawPins" is the function which adds and removes pins.

Lichenin answered 1/8, 2011 at 19:21 Comment(0)
H
-2

There's no reason you can't remove and then re-add the annotation. That's probably way more performant than moving the entire map, even if its a fake move.

Holmium answered 30/7, 2010 at 13:29 Comment(2)
Someone want to explain why this was downvoted? This is at the very least an alternative and I would argue it's more performant.Holmium
I am sure most people who found this thread had already tried this; I know I did. This causes bizarre behavior.Neuron
Z
-7

Here is the interface to MapAnnotation:

//  CSMapAnnotation.h
//  mapLines
//  Created by Craig on 5/15/09.
//  Copyright 2009 Craig Spitzkoff. All rights reserved.

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>    

// types of annotations for which we will provide annotation views. 
typedef enum {
    MapAnnotationTypeStart = 0,
    MapAnnotationTypeEnd   = 1,
    MapAnnotationTypeImage = 2
} MapAnnotationType;

@interface MapAnnotation : NSObject <MKAnnotation>
{
    CLLocationCoordinate2D _coordinate;
    MapAnnotationType      _annotationType;
    NSString*              _title;
    NSString*              _subtitle;
    NSString*              _userData;
    NSString*              speed;
    NSString*              identifier;
}

@property (nonatomic, retain) NSString *speed;
@property (nonatomic, retain) NSString *identifier;

-(id) initWithCoordinate:(CLLocationCoordinate2D)coordinate 
    annotationType: (MapAnnotationType) annotationType
    title: (NSString*) title
    subtitle: (NSString*) subtitle
    speed: (NSString *) speed
    identifier: (NSString *) identifier;    
-(id) setWithCoordinate: (CLLocationCoordinate2D) coordinate 
    annotationType: (MapAnnotationType) annotationType
    title: (NSString*) title
    subtitle: (NSString*) subtitle
    speed: (NSString*) speed
    identifier: (NSString*) identifier;    
@property MapAnnotationType annotationType;
@property (nonatomic, retain) NSString* userData;    
@end    

And here is the implementation:

//  CSMapAnnotation.m
//  mapLines
//  Created by Craig on 5/15/09.
//  Copyright 2009 Craig Spitzkoff. All rights reserved.

#import "MapAnnotation.h"    

@implementation MapAnnotation

@synthesize coordinate     = _coordinate;
@synthesize annotationType = _annotationType;
@synthesize userData       = _userData;
@synthesize speed;
@synthesize identifier;

-(id) initWithCoordinate:(CLLocationCoordinate2D)coordinate 
    annotationType: (MapAnnotationType) annotationType
    title: (NSString*)title
    subtitle: (NSString*) subtitle
    speed: (NSString *) speedz
    identifier: (NSString *) identifierz
{
    self = [super init];
    _coordinate = coordinate;
    _title  = [title retain];
    _subtitle = [subtitle retain];
    _annotationType = annotationType;
    speed = speedz;
    identifier = identifierz;
    return self;
}    
-(id) setWithCoordinate:(CLLocationCoordinate2D)coordinate 
    annotationType: (MapAnnotationType) annotationType
    title: (NSString*) title
    subtitle: (NSString*) subtitle
    speed: (NSString*) speedz
    identifier: (NSString*) identifierz
{
    _coordinate = coordinate;
    _title = [title retain];
    _subtitle = [subtitle retain];
    _annotationType = annotationType;
    speed = speedz;
    identifier = identifierz;       
    return self;
}    
-(NSString*) title
{
    return _title;
}    
-(NSString*) subtitle
{
    return _subtitle;
}    
-(void) dealloc
{
    [_title    release];
    [_userData release];
    [super dealloc];
}    
@end
Zedekiah answered 10/10, 2009 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.