I have a map loaded with pins of the 3 standard colours. These pins get coloured based on a value in an xml that is parsed and stored into an array.
I would like to add a segmented control with 2 buttons:
Button 1 to show only Green Pins.
and Button 2 to show only Red and Purple pins.
I have read about adding 3 different arrays for each pin colour and removing the array of pins but I want to maintain the one array. How would I do this if possible. I know how to implement a segmented control but I stumped on how to filter them on or off.
Heres my for loop: That creates the pins and assigns the 3 colours which works fine.
//Count the array of annotations and add them dynamically to the map.
for (int i = 0; i < locationArray.count; i++) {
myAnnotation =[[MyAnnotation alloc] init];
NSString *latString = [[locationArray objectAtIndex:i]xmlLat];
NSString *lonString = [[locationArray objectAtIndex:i]xmlLon];
type = [[locationArray objectAtIndex:i]xmlType];
imageId = [[locationArray objectAtIndex:i]xmlImageId];
address = [[locationArray objectAtIndex:i]xmlAddress];
email = [[locationArray objectAtIndex:i]xmlEmail];
phone = [[locationArray objectAtIndex:i]xmlPhone];
live = [[locationArray objectAtIndex:i]xmlLive];
form = [[locationArray objectAtIndex:i]xmlForm];
name = [[locationArray objectAtIndex:i]xmlName];
//Change the 0 to Active ticket and 1 to Closed 2 to False and 3 to Not Found and 4 to Other
if ([live isEqualToString:@"0"]) {
live = @"Active";
}
else if ([live isEqualToString:@"1"]){
live = @"Closed";
}
else if([live isEqualToString:@"2"]){
live = @"False";
}
else if ([live isEqualToString:@"3"]){
live = @"Not Found";
}
else if ([live isEqualToString:@"4"]){
live = @"Other";
}
double theLatitude = [latString doubleValue];
double theLongtitude = [lonString doubleValue];
userLocation.latitude=theLatitude;
userLocation.longitude=theLongtitude;
myAnnotation.coordinate=userLocation;
myAnnotation.title=[NSString stringWithFormat:@"%@", imageId];
myAnnotation.subtitle=[NSString stringWithFormat:@"%@", type];
//Setting pin colours here based on value from XML
if ([live isEqualToString:@"Active"]){
myAnnotation.pinColor = MKPinAnnotationColorGreen;
}else if ([live isEqualToString:@"Closed"]){
myAnnotation.pinColor = MKPinAnnotationColorRed;
}
else if ([live isEqualToString:@"Not Found"]){
myAnnotation.pinColor = MKPinAnnotationColorPurple;
}
[incidentsMap addAnnotation:myAnnotation];
}
and heres my segmented control
-(IBAction)segmentedControl:(id)sender{
if (mapFilter.selectedSegmentIndex == 0) {
NSLog(@"Active");
}
else if (mapFilter.selectedSegmentIndex == 1){
NSLog(@"Closed");
//Remove Red and Purple Pins here from view when segmented control button button is touched.........................
}
else if (mapFilter.selectedSegmentIndex == 2){
UIAlertView *mapSelector = [[UIAlertView alloc]initWithTitle:@"Select Map Type" message:@"Choose from 3 map views" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Default", @"Hybrid", @"Satelite", nil];
[mapSelector show];
}
}
The simplest approach is initially and whenever the filter criteria changes (eg. when the segmented control's value changes):
removeAnnotations
(or removeAnnotation
in some loop).locationArray
and only call addAnnotation
for the ones that pass the filter.This may result in some flicker as annotations are removed and added again but is relatively easy to implement.
Another alternative is to do the following (both initially and after the filter changes). Loop through the locationArray
and:
annotations
array, add it to the mapannotations
array, remove it from the mapHowever, this method requires that you have some unique property in your annotation object that can be used to implement the "is already in the map" existence check (using the coordinate is not recommended). You may need to add that unique property to the MyAnnotation
class.
Or, if you kept your own master array of all possible MyAnnotation
objects, you could simply use containsObject
to test if it is in the map's annotations
array.