Hi everyone!
I'm using MKMapView with many annotations. Everything is OK until i zoom in and zoom out my map. Some annotations' location switch with each others. Anyone know why?
Here are my code that i call after viewDidLoad to import annotations from 3 arrays: longitudes, latitudes and photoFileName.
photoFileName contains photo file names for all annotations, longitudes and latitudes contain coordinates of them.
Code:
for (int i=0; i<[longitudes count]; i++)
CLLocation* location = [[CLLocation alloc] initWithLatitude:[latitudes objectAtIndex:i]
longitude:[longitudes objectAtIndex:i]];
CSMapAnnotation* annotation = [[CSMapAnnotation alloc] initWithCoordinate:[location coordinate]
annotationType:CSMapAnnotationTypeImage
title:@"";
subtitle:@"";
// Set data for the annotation. This data is used for displaying annotation
[annotation setUserData:[photoFilename objectAtIndex:i]];
[_mapView addAnnotation:annotation];
[annotation release];
[currentLocation release];
}
You can see the result in attached files. After zooming in and zoom out again, the location of the bridge image (in the bottom) is changed.
Hi everyone!
I'm using MKMapView with many annotations. Everything is OK until i zoom in and zoom out my map. Some annotations' location switch with each others. Anyone know why?
Here are my code:
Code:
for (int i=1; i<[menu.photoLocation count]; i++) {
for (int j=0; j<[[menu.photoLocation objectAtIndex:i] count]; j++) {
NSString *str = [[menu.photoLocation objectAtIndex:i] objectAtIndex:j];
NSRange range = [str rangeOfString:@","];
if (range.length == 0) continue;
CLLocation* currentLocation = [[CLLocation alloc] initWithLatitude:[[str substringToIndex:range.location] floatValue]
longitude:[[str substringFromIndex:(range.location+1)] floatValue]];
CSMapAnnotation* annotation = [[CSMapAnnotation alloc] initWithCoordinate:[currentLocation coordinate]
annotationType:CSMapAnnotationTypeImage
title:[[menu.photoTitle objectAtIndex:i] objectAtIndex:j]
subtitle:[NSString stringWithFormat:@"%d", j]];
//NSLog(@"photo %f %f", currentLocation.coordinate.latitude, currentLocation.coordinate.longitude);
// create the start annotation and add it to the array
[annotation setUserData:[[menu.photoFilename objectAtIndex:i] objectAtIndex:j]];
[annotation setUrl:[NSURL URLWithString:@"http://a.net"]];
[_mapView addAnnotation:annotation];
[annotation release];
[currentLocation release];
}
}
You can see the result in attached files. After zooming, the location of the bridge image is changed.
I don't understand the purpose of the code you posted. What method is that code extracted from, and what is it supposed to do? When does it get called? Is it getting called every time you zoom the map? (It should not be.) What does the menu.photoLocation array contain? What other properties of the menu object are needed for this? I also see properties menu.photoFilename and menu.photoTitle.
It looks like the code is attempting to add an array of photo locations to your annotations. I found the variable names of the code very confusing. You used the name currentLocation, which is used by the map kit to mean the user's current location as reported by the GPS. However, you're setting up currentLocation as a location using float values from a "photoLocation" string. That variable name would make more sense as "photoCLLocation" or similar.
If this is the code that's misbehaving, you might want to set a breakpoint at the line that creates the annotation, and examine the strings you're using and the resulting CLLocation object you're creating.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.
1. It's called 1 time after [super viewDidLoad]. It's an init step to load all annotations of mapview as you can see in the attached pictures.
2. photoFileName is an array that contains all file names of annotations's images.
3. longitudes and latitudes are 2 arrays that contain coordinates of annotations
4. Everything loaded OK, scrolling and zooming worked. However, when I zoom in mapview (about 5-10 times bigger), and after that, zoom out again to the first size, some annotations locations are changed (See the bottom annotation).
I don't post the function viewForAnnotation here because it's not called, i just zoom in/out and it happends.
When dequeueReusableAnnotationViewWithIdentifier function call, it gets a random annotation because of all of them have the same identifier: @"Image".
Solved by specifying each annotation with a different identifier and reuse it:
When dequeueReusableAnnotationViewWithIdentifier function call, it gets a random annotation because of all of them have the same identifier: @"Image".
Solved by specifying each annotation with a different identifier and reuse it:
Actually, your solution is bad. By making every single annotation view have a unique reuse identifier, you're preventing annotation view reuse from occurring at all. You will also cause all formerly used annotation views to be kept around for reuse, so you are maximizing the amount of memory your app will use.
The right solution is to fix your dequeueReusableAnnotationViewWithIdentifier: method so that it takes a reused cell and installs the correct image into it. It's the same logic that you need for recycled table view cells
The logic looks like this, in pseudo-code:
Code:
annotation_view = <dequeue old annotation object>.
if (!annotation_view)
{
create new annotation_view
install "structural" elements (subviews or other allocated objects) into annotation_view
}
//Fall through to this code whether we created a new annotation view or not.
install all values for an annotation view object. In your case, install the correct image.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.