iOS: User location turns into pin - ios

I have a mapView with a strange behavior: When I open it, everything works fine. The user (blue with circles) is going to be located and the 3 pins are in position. But (I don't know why) after a some time, the blue point turns into a pin - but only when I have slow connection speed.
Here's what I got:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView && ![annotation isKindOfClass:[MKUserLocation class]])
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
if (annotation == self.locationZH1)
{
[pinView setTag:1];
}
else if (annotation == self.locationZH2)
{
[pinView setTag:2];
}
else if (annotation == self.locationZH3)
{
[pinView setTag:3];
}
else if (annotation == self.locationLU1)
{
[pinView setTag:4];
}
}
else
{
pinView.annotation = annotation;
}
return pinView;
}

Be sure to avoid providing an annotation view for the built in user location marker.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
//check annotation is not user location
if([annotation isEqual:[mapView userLocation]])
{
//bail
return nil;
}
static NSString *annotationViewReuseIdentifer = #"map_view_annotation";
//dequeue annotation view
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationViewReuseIdentifer];
if(!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationViewReuseIdentifer];
}
//set annotation view properties
[annotationView setAnnotation:annotation];
return annotationView;
}
By checking for the user location annotation earlier, you can provide an early out for returning nil rather than allocating a new MKPinAnnotationView and returning that instead.
The documentation for - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation states:
If the object in the annotation parameter is an instance of the
MKUserLocation class, you can provide a custom view to denote the
user’s location. To display the user’s location using the default
system view, return nil.

Swift 3 Solution :
if annotation is MKUserLocation{
return nil
}

You need to return nil when annotation == mapView.userLocation to show the blue dot for user location and the circle around it
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView && ![annotation isKindOfClass:[MKUserLocation class]])
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
if (annotation == self.locationZH1)
{
[pinView setTag:1];
}
else if (annotation == self.locationZH2)
{
[pinView setTag:2];
}
else if (annotation == self.locationZH3)
{
[pinView setTag:3];
}
else if (annotation == self.locationLU1)
{
[pinView setTag:4];
}
return pinView;
}
else
{
pinView.annotation = annotation;
return Nil;
}
}

Related

User location is showing like annotation

I have multiple Annotation in a MapView, listed in 3 different arrays.
I've used the - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation method to change te Callout of the annotation.
The weird thing is that my UserLocation is changing into an Customised Annotation.
Why is that, and what could be the problem?
How I listed my Annotations:
myAnn = [[Annotations alloc]init];
location.latitude = 52.338847;
location.longitude = 4.937482;
myAnn.coordinate = location;
myAnn.title = #"Afvalpunt";
myAnn.subtitle = #"Rozenburglaan 1";
[category3 addObject:myAnn];
[self.locationArrays addObject:category3];
self.currentAnnotation = 0;
[self.myMapView addAnnotations:[self.locationArrays objectAtIndex:0]];
How my Method is set up:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"MapAn"];
if (!annotationView) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"MapAn"];
annotationView.canShowCallout = YES;
//Blauw Navigatie Auto...
UIImageView *carView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Driving"]];
UIButton *blueView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44+30)];
blueView.backgroundColor = [UIColor colorWithRed:0 green:0.5 blue:1 alpha:1];
carView.frame = CGRectMake(11, 14, carView.image.size.width, carView.image.size.height);
[blueView addTarget:self action:#selector(carClicked) forControlEvents:UIControlEventTouchUpInside];
[blueView addSubview:carView];
annotationView.leftCalloutAccessoryView = blueView;
}
return annotationView;
}
Try this code.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if (annotation == mapView.userLocation) return nil;
...
We return nil if the annotation is userLocation to let the mapView display the blue dot & circle animation. In order to show our custom annotation for userLocation just remove the line return nil; and do your customization there.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString* AnnotationIdentifier = #"Annotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView) {
MKPinAnnotationView *customPinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
if (annotation == mapView.userLocation)
{
customPinView.image = [UIImage imageNamed:#"myCarImage.png"];
}
else
{
customPinView.image = [UIImage imageNamed:#"mySomeOtherImage.png"];
customPinView.animatesDrop = NO;
customPinView.canShowCallout = YES;
return customPinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
Hope this code is useful for you.
Try this code
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]] || annotation==mapView.userLocation)
{
return nil;//Here you can also customise your pin if you dont want pin then just return nil.
}
else
{
//your code
}
}

iOS Mapkit - Annotations disappear on map scroll/zoom

On initial load, the annotations show just fine. But if I scroll the map, they all disappear and the code is only called for the user location, not the other annotations in the viewForAnnotation delegate method.
Plot Pins
-(void)viewDidLoad{
...Download Coordinates and Data from Web here...
[self.mapView addAnnotation:pin];
}
Delegate Method
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
//Player's Pin
if([annotation class] == MKUserLocation.class) {
return nil;
}
//Cluster Pin
if([annotation isKindOfClass:[REVClusterPin class]]){
REVClusterPin *pin = (REVClusterPin *)annotation;
if( [pin nodeCount] > 0 ){
pin.title = #"___";
MKAnnotationView *annotationView = (REVClusterAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"cluster"];
if( !annotationView ){
annotationView = (REVClusterAnnotationView*)
[[REVClusterAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"cluster"];
}
annotationView.image = [UIImage imageNamed:#"cluster.png"];
[(REVClusterAnnotationView*)annotationView setClusterText:
[NSString stringWithFormat:#"%i",[pin nodeCount]]];
annotationView.canShowCallout = NO;
return annotationView;
}
}
//Player Pin
if([annotation isKindOfClass:[ZEPointAnnotation class]]){
ZEPointAnnotation *pin = (ZEPointAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
if(!annotationView){
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pin"];
}
annotationView.canShowCallout = YES;
annotationView.draggable = NO;
...Create Pin Data Here...
return annotationView;
}
return nil;
}
remove animations. that will solve your problem

How to change marker icon?

I was wonderring if there is a way to change those red pins that are used as markers. And if there is a way, how to do it?
you can use 3 types of color pins in mapView are bellow..
MKPinAnnotationColorGreen;
MKPinAnnotationColorPurple
MKPinAnnotationColorRed
and if you want to add customview or image then you can add with programatically
also you can change pin in delegate method of MKMapView like bellow..
- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
if (annotation == _mapView.userLocation)
{
// pinView.pinColor = MKPinAnnotationColorRed;
// return pinView;
return nil;
}
pinView.pinColor = MKPinAnnotationColorGreen; // you can use MKPinAnnotationColorPurple, MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.animatesDrop = NO;
return pinView;
}
and for custom image or pin, use bellow code..
- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
}
annotationView.image = [UIImage imageNamed:#"yourImageName"];//add any image which you want to show on map instead of red pins
annotationView.annotation = annotation;
return annotationView;
}

Why when I press the AnnotationView sometime the image disappear?

In my MapView there are multiple annotationView, each with their own image, it happens that sometimes when I press the image, it disappears and never comes back if not reloading the viewController. Why does this happen?
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id
<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[AnnotationView class]]) {
return nil;
}
if ([annotation isKindOfClass:[AnnotationCustom class]]){
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView *annotationView = (MKPinAnnotationView*) [mapView
dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationIdentifier];
if ([self.nameTable isEqualToString:#"Movies"]){
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone){
annotationView.image = [UIImage imageNamed:#"iphone_movies.png"];
}else{
annotationView.image = [UIImage imageNamed:#"ipad_movies.png"];
}
}else if ([self.nameTable isEqualToString:#"Food_Drink"]){
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone){
annotationView.image = [UIImage imageNamed:#"iphone_foodDrink.png"];
}else{
annotationView.image = [UIImage imageNamed:#"ipad_foodDrink.png"];
}
}else if (......){
//same procedure for all annotationView
}
UIButton *detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.rightCalloutAccessoryView=detailButton;
annotationView.canShowCallout = YES;
annotationView.draggable = YES;
return annotationView;
}
Something is missing?
Are you doing anything in
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
I also noticed that you're not setting the annotation for annotation views. When setting up an annotation view you should also do
annotationView.annotation = annotation;
I replaced
MKPinAnnotationView *annotationView = (MKPinAnnotationView*) [mapView
dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationIdentifier];
with
MKAnnotationView *annotationView = (MKAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
annotationView = [[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];

mapkit show annotation by default

I have an annotation showing in mapkit with a custom image, showing fine,
but the annotation shows after taping the pin,
how can I have the annotation showing by default?, when I start the view? whit out tapping the pin.
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
NSString *annotationIdentifier = #"PinViewAnnotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView *) [mapView
dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:annotationIdentifier] autorelease];
[pinView setPinColor:MKPinAnnotationColorGreen];
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIImageView *houseIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tijereta.png"]];
pinView.leftCalloutAccessoryView = houseIconView;
[houseIconView release];
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
thanks
you can use this
[mapView selectAnnotation:pinView animated:YES]; //here pinView is your annotation and mapview is your map
hope that helped

Resources