Userlocation bubble annotation changing to custom annotation - iphone

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.

Related

MKPinAnnotationView not moving while change location

I am working on location based application in which i need to move MKAnnotation Pin as per the change location. It means as user change location from once place to other the Annotation should be moved.
This is my code of annotation:
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *defaultPinID = #"com.invasivecode.pin";
pinView = (MKPinAnnotationView *)[mV dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if (pinView == nil)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
pinView.enabled = YES;
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.canShowCallout = YES;
}
return pinView;
}
It drops the pin on the current location but when i move with device the location changed & also MKPolyline i have implement but Pin stays there.
see this image :
You can see in this the green pin is the start point & the other side is the current point. So the pin should be on the current point thats what i want.
I have searched & tried few of the solutions of stack but not able to solve my issue.
Any suggestions & help will be highly appreciated.
Thanks in advance.
I got the solution from #AnnaKarenina suggestions thank you so much.
What i have done is make my MKPinAnnotationView global & then :
pinView.annotation.coordinate = newLocation.coordinate;
This line i added into didUpdateToLocation method which allows annotation to get new location every time.
Thanks again.

User Location Strange Issue

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.

MKPinAnnotationView and custom classes conforming to the MKAnnotation protocol

I have created the following method for determining the view for my annotations in a map view.
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
MKPinAnnotationView *pin;
if ([annotation isKindOfClass:[AnnotationsWithIndices class]])
{
int i = [(AnnotationsWithIndices *)annotation index];
if (i > currentCheckpointIndex )
{
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"unvisited"];
if (!pin)
{
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"unvisited"];
}
[pin setPinColor:MKPinAnnotationColorRed];
}
if (i == currentCheckpointIndex)
{
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"current"];
if (!pin)
{
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"current"];
}
[pin setPinColor:MKPinAnnotationColorGreen];
}
if (i < currentCheckpointIndex)
{
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"visited"];
if (!pin)
{
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"visited"];
}
[pin setPinColor:MKPinAnnotationColorPurple];
}
[pin setAnimatesDrop:YES];
return [pin autorelease];
}
else
return nil;
}
The idea is that I want the different annotation views (pins) be of different colors depending on whether the user has visited them to signal which annotation to visit next.
This code works fine, but I have a few questions about it which I hope someone can answer.
Firstly, the MKPinAnnotations are dequeued from a map view and reused whenever possible. In the line doing so (which I have found in multiple blogs and forums)
pin = (MKPinAnnotationView *)[mv dequeueReusableAnnotationViewWithIdentifier:#"unvisited"];
I understand that the return value of the dequeueReusableAnnotationViewWithIdentifier: is an instance of MKAnnotationView, whereas pin is a pointer to an instance of MKPinAnnotationView (which is a subclass o MKAnnotationView). This, I guess, is why there is a 'cast' seemingly going on with the prefix (MKPinAnnotationView *) in front of the method call. Is this really a cast and in this case, is it not dangerous since the MKPinAnnotationView contains more instance variables (than MKAnnotationView) and hence more space in memory?
I have tried to find some information about this, but nowhere I have not found anyone explaining this in particular.
Furthermore, the pointer annotation is either of class MKUserLocation or of my own custom class AnnotationsWithIndices conforming to the MKAnnotation protocol. Now, in order to determine which color the annotation view should have I have added an instance variable called index into the AnnotationsWithIndices class. Now, when I call the getter for the index I write
int i = [(AnnotationsWithIndices *)annotation index];
Now, I basically have the same question about this. Is there a cast going on here or is it just to let the compiler know that it is ok to send the message index to annotation? I guess that the compiler expects annotation to be an id whereas it really is a pointer to an instance of AnnotationsWithIndices.
Of course I know that this is the case since the annotation will be of my custom class, and I also check this explicitly to be sure. Is the (AnnotationsWithIndices) there only to signal to the compiler that this is OK?
I have also tried to find information about this without luck.
I am very thankful for any answers on this.

viewForAnnotation problem-Images are not placing properly on google map in iPhone

In my Application I have to show the google map along with pin images. I have to place two images according to the condition(branch,atm).In viewForAnnotation method I am doing code for the same,in NSLog I am getting the correct output but annotation images aren't placing properly.
Images are placing inconsistently.Here is my code.
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
NSString* identifier = #"Pin";
MKAnnotationView* annView = [searchMapView dequeueReusableAnnotationViewWithIdentifier:identifier];
AddressAnnotation *delegate = annotation;
Location *newLoc = [searchData objectAtIndex:countATMandBranch];
if (annView == nil) {
annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"cell"]autorelease];
annView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
if(newLoc.isATM == YES)
{
annView.image = [UIImage imageNamed:#"map_atmicon.png"];
}
else if(newLoc.isBranch == YES)
{
annView.image = [UIImage imageNamed:#"map_branchicon.png"];
}
//annView.enabled = YES;
annView.tag = mapView.tag;
annView.canShowCallout =YES;
}
countATMandBranch++;
return annView;
}
If any one aware of this kind of issue please reply to my question.
This might be an offset issue.
When you use a custom image for an MKAnnotationView it will by default position it in the center. If you are using a custom 'pin' image this isn't what you want - you want the bottom of the pin to point to the location, rather than the center. If you don't change the offset, when you zoom in/out the position of the annotation will appear to change in comparison to where you think it should be.
You should therefore make sure you've set an appropriate centerOffset on your annotation view. I don't see you setting it in the code above, so unless you want your image to be centered exactly on the coordinates required this is probably what's causing it.

add overlays to existing pins in viewcontroller.m

I'm new to programming and obj-c and currently working on a map based iphone app which will locate different sport facilities. I want each pin to show a different overlay, for instance a picture overlay will do fine, I'll add pics into the resource folder and I want each pin to reveal a different picture by clicking it. My example only includes one pin with its cordinates.
Now, I have now clue where to start, hope u can help me out!
thanks in advance :)
Here's my code:
[mapView addAnnotation:[MapLocation mapLocationtWithTitle:#"Beckomberga Sim och Sporthall" subtitle:#"Söderberga Allé 80" andCoordinate:(CLLocationCoordinate2D){ 59.35817, 17.89740 }]];
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MapLocation class]])
{
MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"PinAnnotation"];
pin.canShowCallout = YES;
pin.animatesDrop = NO;
pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pin.pinColor = MKPinAnnotationColorRed;
pin.pinColor = MKPinAnnotationColorGreen;
[pin autorelease];
return pin;
}
return nil;
}
Viktor,
Here is what you need to do:
Create a subobject of MKAnnotation that will represent your locations, SportsFacilityLocation
That object will contain title, subtitle, and location fields. This is to conform to the MKAnnotation protocol
Next you need an object that will be a subclass of MKAnnotationView, SportsFacilityMapView.
Finally in your viewForAnnotation delegate method you need to check each annotation type
and from that annotation type you will determine to return your SportsFacilityMapView
Check the docs on how to implement the Annotation and then AnnotationView. I have some example code at home that I will post later if you need it. Good Luck!