I created a custom view for user location using :
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
if([annotation class]==[MKUserLocation class])
{
//my code to return the pin
}
else
{
//code for custom pin
}
After some user action i update setShowsUserLocation to NO for the mapview. Then I start core location controller which uses a different custom pin view to track user location. THe original pin dissappears for sometime but then reappears later on when i drag or pinch to zoom on the map. while debugging i saw that it enters the if condition above was called inspite of setShowsUserLocation being set to no.
Related
I have all concept of Maps how it works but I am stuck in very strange issue.
As soon as open my Map Controller my default blue is visible (MKUserLocation) but when I am loading custom pins (IVMyLocation, Annotation class), default pin disappear.
I am properly managing removing of custom pins so that default pin shouldn't disappear like
for (id<MKAnnotation> annotation in _mapView.annotations) {
if([annotation isKindOfClass:[IVMyLocation class]])
[_mapView removeAnnotation:annotation];
}
But still my default pin is disappearing. Its only visible first time.
NOTE: Its working fine in Xcode4 simulator its disappearing in only device
You should return nil for the MKUserLocation in mapView:viewForAnnotation:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// etc
This allows the default blue dot to show.
Reduce your objects count. Helped for me.
I am adding a custom annotation along with the user's current location default bubble annotation but the user location annotation is changing to the other custom location after sometime when not in focus on mapview.
My viewForAnnotation method is :
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
NSString* annotationidentifier = #"customview";
CustomAnnotationView *customannotationview = (CustomAnnotationView*) [self.mapview dequeueReusableAnnotationViewWithIdentifier:annotationidentifier];
if([annotation isKindOfClass:[MKUserLocation class]])
{
customannotationview = [[CustomAnnotationView alloc] initWithAnnotationWithImage:annotation reuseIdentifier:annotationidentifier annotationviewimage:[UIImage imageNamed:#"location pin28.png"]];
customannotationview.canShowCallout = YES;
return customannotationview;
}
else if(![annotation isKindOfClass:[MKUserLocation class]] && annotation != _mapview.userLocation && (annotation.coordinate.latitude != _locationmanager.location.coordinate.latitude && annotation.coordinate.longitude != _locationmanager.location.coordinate.longitude))
{
customannotationview = [[CustomAnnotationView alloc] initWithAnnotationWithImage:annotation reuseIdentifier:annotationidentifier annotationviewimage:[UIImage imageNamed:#"image1.png"]];
return customannotationview;
}
return customannotationview;
}
I have put conditions in the custom annotation but still after some time if userlocation is out of focus for somtime it changes to image1.png
I believe your issue is the fact that both your user annotation and location annotation use the same identifier. What happens is, when you scroll the map around, your annotations get reused (the same way a table would reuse cells), and eventually, one of your location annotations is used for your user annotation.
Try giving the annotations different identifiers, or, if you have a small number of locations, remove the reuse code, that should fix it.
I'm hoping someone can point me to a convenient delegate method to answer the following question.
My question is: How do I know that the user has been located by MapKit for the first time?
When my view appears, I'd tell my MKMapView locate the user and set the map region around the user. After initially finding the user, I don't want to keep updating the map to his/her location. I want to give the user the freedom to pan around the map and not get automatically taken back to their location.
I'm having trouble when there's a delay in locating the user (for example, the very first time the user opens the app, MapKit doesn't locate the user until the he/she agrees to share their location). The result is that the map opens up somewhere over the Atlantic Ocean, and it doesn't correct itself once the user is found.
Unfortunately, -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation gets called a couple times before the user's real location has been determined (When testing, I see its NSLog statements before I ever agree to share my location).
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate=self;
}
-(void)viewWillAppear:(BOOL)animated{
[self.mapView setShowsUserLocation:YES];
[self.mapView setUserTrackingMode: MKUserTrackingModeNone];
hasUpdatedRegion=NO;
}
//MapKit Delegate Methods
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(#"didUpdateUserLocation");
if(!hasUpdatedRegion)
{
hasUpdatedRegion=YES;
MKCoordinateSpan span=MKCoordinateSpanMake(0.3, 0.3);
MKCoordinateRegion currentRegion=MKCoordinateRegionMake(mapView.userLocation.coordinate, span);
[mapView setRegion:currentRegion];
}
}
-(void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated{
NSLog(#"didChangeTrackingMode");
}
I have the same problem. Made another way...
- (void)viewDidLoad
{
self.mapView.userTrackingMode = YES;
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
self.mapView.userTrackingMode = NO;
}
First, set userTrakingMode to YES track the user as s/he moves.
Second, after updating map to user location didUpdateUserLocation is fired, when I've disabled the tracking mode.
This stops the map from tracking the user any more.
Why don't you , try setting the mapview region , so that the whole world map shows instead of a particular location(as u said 'Atantic ocean'), in case of user didn't allow the mapkit to use current location(i mean in view did load method ,set the map region .),,and if he allows..then set the region as per user's coordinates,.
I'm wondering...how to know that that method is no more being called?
method:
mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
}
How to know the above method is no more called?
(From the comments:)
I have a method add location which calculates le coordinates from an array of coordinates and places them on the map, then the mapView:(MKMapView *) mapView viewForAnnotation:(id ) annotation { } is being called to place the different custom image instead of the pins...
this takes around 30 seconds....
meanwhile I have started to animate an activity indicator so as the user does not think that the app has crashed....
I want to stop the activity indicator when it has finished...
You can use the didAddAnnotationViews delegate method to tell when the annotation views have been displayed on the map and stop the activity indicator there:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
[activityIndicator stopAnimating];
}
But you may want to look into whether it's possible to reduce the time it takes to add the annotations in the first place since 30 seconds is a long time. Maybe you could only add the annotations that would be visible in the current region.
How can I add the "Pulsating blue circle" in my gps application.
Currently i am fetching my current location by CCLocationManager.
I am using mapView.showsUserLocation = True, but this only display a pin at my current location.
How can i get that "blue circle" as in the default maps app.
update: many app does this. for example - Realtor.com
Thanks
Implement the delegate method:
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation: (id<MKAnnotation>)annotation
and return nil if if (annotation == mv.userLocation). This tell the MKMapView to use whatever standard annotation it deems appropriate.
if (annotation == Current Location){
return nil;
}else{
}