Hello friend in my application i am showing multiple pins on mapview. I have two mutablearray first for latitude and second for longitude each array have 10 values as i am showing bellow code in my method:
- (void)showAddressAllBusiness {
annotationsarray=[[NSMutableArray alloc] init];
NSLog(#"%d",[listOfLatitude count]);
NSLog(#"%d",[listOfLongitude count]);
NSLog(#"%d",[listOfPlaceName count]);
for (int i =0;i < [listOfLatitude count]; i++) {
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = [[listOfLatitude objectAtIndex:i] doubleValue];
region.center.longitude = [[listOfLongitude objectAtIndex:i] doubleValue];
region.span.longitudeDelta = 0.1f;
region.span.latitudeDelta = 0.1f;
[self.mapViewCityGuide setRegion:region animated:YES];
[self.mapViewCityGuide setZoomEnabled:YES];
addAnnotation = [[AddressAnnotation alloc]init];
addAnnotation.mTitle = [NSString stringWithFormat:#"%#",[listOfPlaceName objectAtIndex:i]];
addAnnotation.coordinate = region.center;
[self.mapViewCityGuide addAnnotation:addAnnotation];
[annotationsarray addObject:addAnnotation];
}
NSLog(#"%d",[self.mapViewCityGuide.annotations count]);
[self centerMap];
}
when i am using latitude and longitude array values which is appear from webservice then
this code is not working fine and i am debugg the code then mapViewCityGuide getting nil or 0x0.
If i am using hard code latitude and longitude value as mention bellow in the array and call this method then it will show all pins on map how can i solve this problem
listOfPlaceName = [[NSMutableArray alloc] initWithObjects:#"test",#"test",#"test",#"pithempur",#"test",#"test",#"test",#"test", nil];
listOfLatitude = [[NSMutableArray alloc] initWithObjects:#"22.71957",#"23.17930",#"22.96123",#"22.60987",#"22.45260",#"22.55244",#"22.60000",#"22.68330", nil];
listOfLongitude = [[NSMutableArray alloc] initWithObjects:#"75.85773",#"75.78491",#"76.05141",#"75.69644",#"75.94197",#"75.75653",#"75.30000",#"75.61670", nil];
[self showAddressAllBusiness];
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
mapView.delegate=self;
[mapView removeAnnotations:mapView.annotations];
NSMutableArray* annotations=[[NSMutableArray alloc] init];
for (int j=0; j<10; j++)
{
CLLocationCoordinate2D theCoordinate1;
theCoordinate1.latitude = [[NSString stringWithFormat:#"%i",10+j]doubleValue];
theCoordinate1.longitude = [[NSString stringWithFormat:#"%i",72+j]doubleValue];
//my annotation is mkannotation class
MyAnnotation* myAnnotation1=[[MyAnnotation alloc] init];
myAnnotation1.coordinate=theCoordinate1;
myAnnotation1.title=[NSString stringWithFormat:#"locatiion %i",j];
[mapView addAnnotation:myAnnotation1];
[annotations addObject:myAnnotation1];
}
NSLog(#"%d",[annotations count]);
MKMapRect flyTo = MKMapRectNull;
for (id <MKAnnotation> annotation in annotations) {
NSLog(#"fly to on");
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(flyTo)) {
flyTo = pointRect;
} else {
flyTo = MKMapRectUnion(flyTo, pointRect);
}
}
mapView.visibleMapRect = flyTo;
}
#pragma mark MKMapViewDelegate
/*
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
return [kml viewForOverlay:overlay];
}
*/
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"welcome into the map view annotation");
if ([annotation isKindOfClass:[MyAnnotation class]])
{
static NSString *AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
}
else
{
pinView.annotation = annotation;
pinView.tag=((MyAnnotation *)annotation).tag;
pinView.canShowCallout = YES;
pinView.animatesDrop = NO;
}
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
rightButton.frame=CGRectMake(0, 0, 14, 16);
[rightButton setBackgroundImage:[UIImage imageNamed:#"arrow_s5.png"] forState:UIControlStateNormal];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
rightButton.tag=((MyAnnotation *)annotation).tag;
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
return pinView;
}
return nil;
}
*Please try this code:-*
-(void)viewDidLoad
{
CLLocation *userLoc = mapView.userLocation.location;
CLLocationCoordinate2D userCoordinate = userLoc.coordinate;
NSLog(#"user latitude = %f",userCoordinate.latitude);
NSLog(#"user longitude = %f",userCoordinate.longitude);
mapView.delegate=self;
NSMutableArray* annotations=[[NSMutableArray alloc] init];
MyAnnotation* myAnnotation;
for (int i = 0; i<[DataArr count]; i++)
{
CLLocationCoordinate2D theCoordinate;
double a = [[[DataArr objectAtIndex:i] valueForKey:#"lat"] doubleValue];
double b =[[[DataArr objectAtIndex:i] valueForKey:#"lon"] doubleValue];
theCoordinate.latitude = a;
theCoordinate.longitude =b;
myAnnotation=[[MyAnnotation alloc] init];
NSString *str=[NSString stringWithFormat:#"%d",i];
[myAnnotation indexOfAccessibilityElement:str];
myAnnotation.coordinate=theCoordinate;
myAnnotation.title=[[DataArr objectAtIndex:i] valueForKey:#"name"];
myAnnotation.ID_map=i;
[annotations addObject:myAnnotation];
}
for (int i =0; i<[annotations count]; i++)
{
[mapView addAnnotation:[annotations objectAtIndex:i]];
}
// Walk the list of overlays and annotations and create a MKMapRect that
// bounds all of them and store it into flyTo.
MKMapRect flyTo = MKMapRectNull;
for (id <MKAnnotation> annotation in annotations)
{
NSLog(#"fly to on");
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(flyTo))
{
flyTo = pointRect;
} else
{
flyTo = MKMapRectUnion(flyTo, pointRect);
//NSLog(#"else-%#",annotationPoint.x);
}
}
// Position the map so that all overlays and annotations are visible on screen.
mapView.visibleMapRect = flyTo;
}
#pragma mark MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
NSLog(#"didSelectAnnotationView");
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"welcome into the map view annotation");
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// try to dequeue an existing pin view first
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
pinView.pinColor=MKPinAnnotationColorPurple;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"profile.png"]];
pinView.leftCalloutAccessoryView = profileIconView;
[profileIconView release];
return pinView;
}
I want to show the title of the pin(MKAnnotation)every time when I added the annotation.I added the following code for that.But it is not working.Please help me to find out.
I just added the pin like this.
ann = [[DisplayMap alloc] init];
ann.title = #"aaa";
ann.subtitle = #"bbbn";
[mapView addAnnotation:ann];
after that i added the following code in this method
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"com.invasivecode.pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
pinView.selected = YES;
[mapView selectAnnotation:annotation animated:YES];
//[pinView setImage:[UIImage imageNamed:#"user.png"]];
}
}
what mistake I have done?
In my viewDidLoad: method I have set the MapView like this so that if user has selected all the locations then it should show all the locations/pin views and if only one then only one pin view should be shown.
- (void)viewDidLoad{
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
if ([vehicleLabel.text isEqualToString:#"All Vehicles"]) {
MKCoordinateRegion region = {{0.0, 0.0},{0.0, 0.0}};
region.center.latitude = 41.01860;
region.center.longitude = 28.96470;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
Annotations *ann = [[Annotations alloc] init];
ann.title = #"Vehicle A";
ann.subtitle = #"VG 1";
ann.coordinate = region.center;
[mapView addAnnotation:ann];
NSMutableArray* annotations=[[NSMutableArray alloc] init];
CLLocationCoordinate2D theCoordinate1;
theCoordinate1.latitude = 41.01760;
theCoordinate1.longitude = 30.96470;
CLLocationCoordinate2D theCoordinate2;
theCoordinate2.latitude = 41.01860;
theCoordinate2.longitude = 31.96470;
CLLocationCoordinate2D theCoordinate3;
theCoordinate3.latitude = 41.01360;
theCoordinate3.longitude = 25.96470;
CLLocationCoordinate2D theCoordinate4;
theCoordinate4.latitude = 41.01560;
theCoordinate4.longitude = 27.96470;
Annotations* myAnnotation1=[[Annotations alloc] init];
myAnnotation1.coordinate=theCoordinate1;
myAnnotation1.title=#"Vehicle B";
myAnnotation1.subtitle=#"Group 1";
Annotations* myAnnotation2=[[Annotations alloc] init];
myAnnotation2.coordinate=theCoordinate2;
myAnnotation2.title=#"Vehicle C";
myAnnotation2.subtitle=#"Group 1";
Annotations* myAnnotation3=[[Annotations alloc] init];
myAnnotation3.coordinate=theCoordinate3;
myAnnotation3.title=#"Vehicle D";
myAnnotation3.subtitle=#"Group 1";
Annotations* myAnnotation4=[[Annotations alloc] init];
myAnnotation4.coordinate=theCoordinate4;
myAnnotation4.title=#"Vehicle E";
myAnnotation4.subtitle=#" Group 1";
[mapView addAnnotation:myAnnotation1];
[mapView addAnnotation:myAnnotation2];
[mapView addAnnotation:myAnnotation3];
[mapView addAnnotation:myAnnotation4];
[annotations addObject:myAnnotation1];
[annotations addObject:myAnnotation2];
[annotations addObject:myAnnotation3];
[annotations addObject:myAnnotation4];
NSLog(#"Annotations: %d",[annotations count]);
}
else {
MKCoordinateRegion region = {{0.0, 0.0},{0.0, 0.0}};
region.center.latitude = 41.01860;
region.center.longitude = 28.96470;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
Annotations *ann = [[Annotations alloc] init];
ann.title = #"Vehicle A";
ann.subtitle = #"VG 1";
ann.coordinate = region.center;
[mapView addAnnotation:ann];
}}
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation{
MKPinAnnotationView *pinView = nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"aPin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
} else {
}
pinView.pinColor = MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
return pinView;}
And in my PickerView didSelectRow method: I have implemented:
-(void)pickerView:(UIPickerView *)pickerViewG didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if (component == kGroupComponent) {
NSString *selectedState = [self.vehicleGroup objectAtIndex:row];
NSArray *array = [groupVehicles objectForKey:selectedState];
self.vehiclesList = array;
[vehiclePicker selectRow:0 inComponent:kListComponent animated:YES];
[vehiclePicker reloadComponent:kListComponent];
}
NSInteger groupRow = [vehiclePicker selectedRowInComponent:kGroupComponent];
NSInteger vehicleRow = [vehiclePicker selectedRowInComponent:kListComponent];
NSString *group = [self.groupOfVehicles objectAtIndex:groupRow];
NSString *vehicle = [self.listVehicles objectAtIndex:vehicleRow];
groupLabel.text = [[NSString alloc] initWithFormat: #"%#", group];
vehicleLabel.text = [[NSString alloc] initWithFormat: #"%#", vehicle];
valueForOtherView = vehicleLabel.text;}
Here what I want to know is that what if user selects a single vehicle from the picker view then all other pin views/ locations should be hidden/removed from the view and the only selected location/ pin view should be shown.
How can I do that in this picker view didSelectRow method: ?
What I'm doing in a case similar to yours, is:
1) remove first all the annotations
for (id <MKAnnotation> anAnnotation in [NSArray arrayWithArray:mapView_.annotations]) {
[mapView_ removeAnnotation:anAnnotation];
}
2) and then paint the ones selected:
[mapView_ addAnnotation:myAnnotation];
viewForAnnotation is not being called until I move or zoom in on the map. Because of this, my annotations do not show until the map is touched. Any idea why?
NSString *incident;
for (incident in weekFeed) {
NSString *finalCoordinates = [[NSString alloc] initWithFormat:#"%#", [incident valueForKey:#"coordinates"]];
NSArray *coordinatesArray = [finalCoordinates componentsSeparatedByString:#","];
latcoord = (#"%#", [coordinatesArray objectAtIndex:0]);
longcoord = (#"%#", [coordinatesArray objectAtIndex:1]);
// Final Logs
NSLog(#"Coordinates in NSString: [%#] - [%#]", latcoord, longcoord);
CLLocationCoordinate2D coord;
coord.latitude = [latcoord doubleValue];
coord.longitude = [longcoord doubleValue];
DisplayMap *ann = [[DisplayMap alloc] init];
ann.title = [NSString stringWithFormat: #"%#", [incident valueForKey:#"incident_type"]];
ann.subtitle = [NSString stringWithFormat: #"%#", [incident valueForKey:#"note"]];
ann.coordinate = coord;
[mapView addAnnotation:ann];
[ann release];
}
// Custom Map Markers
-(MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil; //return nil to use default blue dot view
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil) {
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
}
annotationView.canShowCallout = YES;
if ([annotationView.annotation.title isEqualToString:#"one"]) {
UIImage *pinImage = [UIImage imageNamed:#"marker_1.png"];
[annotationView setImage:pinImage];
}
if ([annotationView.annotation.title isEqualToString:#"two"]) {
UIImage *pinImage = [UIImage imageNamed:#"marker_2.png"];
[annotationView setImage:pinImage];
}
annotationView.annotation = annotation;
return annotationView;
}
- (void) mapView:(MKMapView *)mapV didAddAnnotationViews:(NSArray *)views {
CGRect visibleRect = [mapV annotationVisibleRect];
for (MKAnnotationView *view in views) {
CGRect endFrame = view.frame;
CGRect startFrame = endFrame; startFrame.origin.y = visibleRect.origin.y - startFrame.size.height;
view.frame = startFrame;
[UIView beginAnimations:#"drop" context:NULL];
[UIView setAnimationDuration:0.4];
view.frame = endFrame;
[UIView commitAnimations];
}
}
I solved it by using [self performSelectorInBackground:#selector(loadEverything) withObject:self]; instead of detachThreadSelector. That code (in viewDidLoad) wasn't originally posted.
Thanks for helping everyone!
ok desperation. This is killing me.. I totally do not understand MapKit at all.. Despite reading so many tutorial.. =(
For more information, I have 2 annotation classes - MyAnnotation and MyAnnotation2, it doesnt seems to work too.. Somebody plz help.. I am afraid I have no hair left soon =(
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
_annotations = [[NSMutableArray alloc] init];
_annotation2 = [[NSMutableArray alloc] init];
CLLocation *userLoc = _mapView.userLocation.location;
CLLocationCoordinate2D userCoordinate = userLoc.coordinate;
NSLog(#"user latitude = %f",userCoordinate.latitude);
NSLog(#"user longitude = %f",userCoordinate.longitude);
_listOfPolyClinics = [[NSMutableArray alloc] init];
_listOfPatients = [[NSMutableArray alloc] init ];
for (PolyClinics *polyclinics in [[PatientDatabase database]
polyClinics]){
[_listOfPolyClinics addObject:polyclinics];
}
NSLog(#"%i", [_listOfPolyClinics count]);
for (PatientDetails *patientDetails in [[PatientDatabase database]
patientCategoryList:_category]){
[_listOfPatients addObject:patientDetails];
}
NSLog(#"%i", [_listOfPatients count]);
for (PolyClinics *polyclinics in _listOfPolyClinics){
MyAnnotation * myAnnotation =[[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.longitude = polyclinics.longtitude;
theCoordinate.latitude = polyclinics.latitude;
myAnnotation.pinColor = MKPinAnnotationColorPurple;
myAnnotation.coordinate = theCoordinate;
myAnnotation.title = polyclinics.name;
myAnnotation.subtitle = [NSString stringWithFormat:#"%i",polyclinics.telephone];
//myAnnotation.annotationsPatients =
[_mapView addAnnotation:myAnnotation];
[_annotation2 addObject:myAnnotation];
}
for(PatientDetails *patientDetails in _listOfPatients){
MyAnnotation2 * myAnnotation =[[MyAnnotation2 alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.longitude = patientDetails.longitude;
theCoordinate.latitude = patientDetails.latitude;
myAnnotation.pinColor = MKPinAnnotationColorGreen;
myAnnotation.coordinate = theCoordinate;
myAnnotation.title = patientDetails.nric;
myAnnotation.subtitle = [NSString stringWithFormat:#"%i",patientDetails.category];
[_mapView addAnnotation:myAnnotation];
[_annotation2 addObject:myAnnotation];
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"%i", [_annotation2 count]);
MKPinAnnotationView *pinView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:[annotation title]];
for(id <MKAnnotation> a in _annotation2){
if([a isKindOfClass:[MyAnnotation class]]){
pinView.pinColor = MKPinAnnotationColorPurple;
}
else{
pinView.pinColor = MKPinAnnotationColorGreen;
}
pinView.animatesDrop=NO;
pinView.canShowCallout=YES;
return [pinView autorelease];
}
return pinView;
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
is called every time the MKMapView needs to show a view for an annotation, it passes you that annotation for a reason. So instead of iterating through them and returning only the color for the first one in your array (you need to understand that returning from a function/method doesn't let the loop iterate more), use the parameter instead.
Also a good practice is to use
- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier;
so the AnnotationViews don't get created again from scratch, especially memory-wise!
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
BOOL isGreen = YES;
if([annotation isKindOfClass:[MyAnnotation class]])
isGreen = NO;
MKPinAnnotationView *pinView = nil;
if (isGreen) {
static NSString *greenPin = #"greenPin";
pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:greenPin];
if (!pinView) {
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:greenPin] autorelease];
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.animatesDrop = NO;
pinView.canShowCallout = YES;
}
else
pinView.annotation = annotation;
}
else {
static NSString *purplePin = #"purplePin";
pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:purplePin];
if (!pinView) {
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:purplePin] autorelease];
pinView.pinColor = MKPinAnnotationColorPurple;
pinView.animatesDrop = NO;
pinView.canShowCallout = YES;
}
else
pinView.annotation = annotation;
}
return pinView;
}