I have an app in which I use a google API to find places near a user. If they tap a cell named "ATM" on my table view, they are directed to a MapView which will display their user location on the map. They then have to press ANOTHER button called "show" on the screen to plot the points on the nearest ATM's. I want my app to run so that they don't have to press the second button, and once the map loads their user location, the app searches for the nearest "xyz's" near them. Here is the code for my querySearch:
-(void) queryGooglePlaces: (NSString *) googleType
{
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=%#&types=%#&sensor=true&key=%#", currentCentre.latitude, currentCentre.longitude, [NSString stringWithFormat:#"%i", currenDist], googleType, kGOOGLE_API_KEY];
//Formulate the string as URL object.
NSURL *googleRequestURL=[NSURL URLWithString:url];
// Retrieve the results of the URL.
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
Here is the method I want to eliminate. I want this code to run once the map has focused on the user's location:
- (IBAction)showPlace:(id)sender {
NSString *lowerString = [tappedString lowercaseString];
[self queryGooglePlaces:lowerString];
}
And lastly, here are my MapView delegate method's incase they help:
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
//Zoom back to the user location after adding a new set of annotations.
//Get the center point of the visible map.
CLLocationCoordinate2D centre = [mv centerCoordinate];
MKCoordinateRegion region;
//If this is the first launch of the app then set the center point of the map to the user's location.
if (firstLaunch) {
region = MKCoordinateRegionMakeWithDistance(locationManager.location.coordinate,1000,1000);
firstLaunch=NO;
}else {
//Set the center point to the visible region of the map and change the radius to match the search radius passed to the Google query string.
region = MKCoordinateRegionMakeWithDistance(centre,currenDist,currenDist);
}
//Set the visible region of the map.
[mv setRegion:region animated:YES];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
//Define our reuse indentifier.
static NSString *identifier = #"MapPoint";
if ([annotation isKindOfClass:[MapPoint class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.animatesDrop = YES;
return annotationView;
}
return nil;
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
//Get the east and west points on the map so we calculate the distance (zoom level) of the current map view.
MKMapRect mRect = self.mapView.visibleMapRect;
MKMapPoint eastMapPoint = MKMapPointMake(MKMapRectGetMinX(mRect), MKMapRectGetMidY(mRect));
MKMapPoint westMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), MKMapRectGetMidY(mRect));
//Set our current distance instance variable.
currenDist = MKMetersBetweenMapPoints(eastMapPoint, westMapPoint);
//Set our current centre point on the map instance variable.
currentCentre = self.mapView.centerCoordinate;
}
call - (IBAction)showPlace:(id)sender this method using perform selector once you have fetched all the data.
Use MKMapViewDelegate to know when the user has been found:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSString *lowerString = [tappedString lowercaseString];
[self queryGooglePlaces:lowerString];
}
MKMapViewDelegate reference
You should nest the dispatch_sync block inside dispatch_async block. Try like this:
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
dispatch_sync(kBgQueue, ^{
[self fetchedData:data];
})
});
Related
I have several annotation points. What I want to do is when I click an annotation point I want to display that data. I have a custom Annotation class with a title and an NSDictionary. The dictionary contains an image URL and ID. I want to fetch these when I click on a specific annotation.
EDIT: I know about the didSelectAnnotation, but how do I access the data?
-(void)annotations{
CLLocationCoordinate2D pinPoint;
for (NSDictionary * dict in _dataArray) {
pinPoint.latitude =[[dict valueForKey:#"lat"] doubleValue];
pinPoint.longitude = [[dict valueForKey:#"lng"] doubleValue];
_myAnnotation = [[MapViewAnnotation alloc]initWithTitle:[dict valueForKey:#"name"]andCoordinate:pinPoint andData:dict];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:pinPoint addressDictionary:nil] ;
_destination = [[MKMapItem alloc] initWithPlacemark:placemark];
_myAnnotation.title=[dict valueForKey:#"name"];
[self.mapKit addAnnotation:_myAnnotation];
}
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapKit setRegion:[self.mapKit regionThatFits:region] animated:YES];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(MapViewAnnotation*)annotation
{
// If it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// Handle any custom annotations.
if ([annotation isKindOfClass:[MapViewAnnotation class]])
{
// Try to dequeue an existing pin view first.
MKAnnotationView *pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if (!pinView)
{
// If an existing pin view was not available, create one.
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
NSLog(#"%#",[annotation.data valueForKey:#"name"]);
pinView.image = [UIImage imageNamed:#"image"];
pinView.calloutOffset = CGPointMake(0, 32);
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
} else {
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
[request setTransportType:MKDirectionsTransportTypeWalking];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = _destination;
request.requestsAlternateRoutes = NO;
MKDirections *directions =
[[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
// Handle Error
} else {
[self showRoute:response];
}
}];
}
EDIT 2nd :
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
MapViewAnnotation * annotation = (MapViewAnnotation *) view;
NSLog(#"%#",[annotation.data valueForKey:#"name"]);
NSURL *url =[NSURL URLWithString:[[NSUserDefaults standardUserDefaults] objectForKey:#"SPOTTD_profilePic"]];
NSData *imageData = [NSData dataWithContentsOfURL:url];
_imgMyProfile.image = [UIImage imageWithData:imageData];
}
You can use the didSelectAnnotationView method, in combination with the annotation property of the MKAnnotationView:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
if ([view.annotation isKindOfClass:[MapViewAnnotation class]]) {
MapViewAnnotation *annotation = (MapViewAnnotation)view.annotation;
}
}
After you have safely cast the annotation to your custom type, you can access its properties like the NSDictionary.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSString *latPoint2 = [NSString stringWithFormat:#"%.6f", view.annotation.coordinate.latitude];
NSString *longPoint2 =[NSString stringWithFormat:#"%.6f", view.annotation.coordinate.longitude];
There is one more method for annotation which is
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{}.In this method you can show your data on click of annotation.Hope this will help you. If any query let me know. Thanks
i am newbie in iOS Development and new in map kit i want to know about Latitude and Longitude of MapView Center Every time Like as When User Scrollfrom one location to Another then i want to Show Center Latitude and Longitude of my GMSMapView how it Possible like as Here i Attach Image for it.
Here my Current Location is Mumbai Then It Shows My mapView like as
and i want to know Center Location Latitude and Longitude like as when user Scroll Mapview then i want to Know Latitude and Longitude of My Image Indicator Point. Here image Show as i want to Know Latitude and Longitude of this Point Here My Image indicated is in Center Position of my MapView.
To get the position whenever the map is moved, you'd want to handle mapView:didChangeCameraPosition:.
Then inside that method, you can access mapView.camera.target to get the current centre of the map.
- (void) mapView: (GMSMapView *)mapView
didChangeCameraPosition: (GMSCameraPosition *)position
{
double latitude = mapView.camera.target.latitude;
double longitude = mapView.camera.target.longitude;
// now do something with latitude and longitude
}
Note that to handle the delegate method, you'll need to implement the GMSMapViewDelegate protocol. When setting up the map, you'd need to set the map's delegate to the class which handles the protocol (usually self), eg:
mapView.delegate = self;
Use below code for getting center of mapview latitude and longitude .
When ever you scroll mapview in any direction automatically regionWillChangeAnimated: method will call.It's one of the optinal delegate method.
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(mkmapView.centerCoordinate.latitude, mkmapView.centerCoordinate.longitude);
CGFloat txtLatitude = coord.latitude;
CGFloat txtLongitude = coord.longitude;
NSLog(#"Latitude is===>>>%f %f",txtLongitude);
NSLog(#"Longitude is===>>>%f %f",txtLongitude);
}
If you tap the map view,you need that Latitude and Longitude use below code.
Here _mkMapView is outlet of Mapview.
- (void)viewDidLoad
{
UITapGestureRecognizer *tapGesture= [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backgroundTapped:)];
[self.view addGestureRecognizer:tapGesture];
}
- (void)backgroundTapped:(UITapGestureRecognizer *)gesture
{
CGPoint touchPoint = [gesture locationInView:_mkMapView];
CLLocationCoordinate2D location =[_mkMapView convertPoint:touchPoint toCoordinateFromView:_mkMapView];
}
may be it will helpful for you.
- (void)mapView:(GMSMapView *)pMapView didChangeCameraPosition:(GMSCameraPosition *)position {
mapViewRef.delegate = self;
double latitude = mapViewRef.camera.target.latitude;
double longitude = mapViewRef.camera.target.longitude;
CLLocationCoordinate2D addressCoordinates = CLLocationCoordinate2DMake(latitude,longitude);
GMSGeocoder* coder = [[GMSGeocoder alloc] init];
[coder reverseGeocodeCoordinate:addressCoordinates completionHandler:^(GMSReverseGeocodeResponse *results, NSError *error) {
if (error) {
// NSLog(#"Error %#", error.description);
} else {
GMSAddress* address = [results firstResult];
NSArray *arr = [address valueForKey:#"lines"];
NSString *str1 = [NSString stringWithFormat:#"%lu",(unsigned long)[arr count]];
if ([str1 isEqualToString:#"0"]) {
self.txtPlaceSearch.text = #"";
}
else if ([str1 isEqualToString:#"1"]) {
NSString *str2 = [arr objectAtIndex:0];
self.txtPlaceSearch.text = str2;
}
else if ([str1 isEqualToString:#"2"]) {
NSString *str2 = [arr objectAtIndex:0];
NSString *str3 = [arr objectAtIndex:1];
self.txtPlaceSearch.text = [NSString stringWithFormat:#"%#,%#",str2,str3];
}
}
}];
}
I am new to xcode and i hope someone can help me with my code, and point me how to solve my issue. i've been looking at the internet, but really i couldnt figure it out.
How can i go from a map view to a detail view, bringing the "ID" of the pin with it and print it in a label.
when i click on the arrow for the annotation, my simulator crashes.
Please any ideas, how to approach it and solve it ?
( basicly i want to get the ID of the pin, and send it to a server through JSON and then move to the Detailview, but the next step )
Here is what i did so far :
My Location.m ( view controller for the map )
#import "My_Location.h"
#import "DetailViewController.h"
// ------ FUNCTION TO GET COORDINATES IN JSON FORMAT -------
- (void)retrieveData_Location
{
NSURL * url = [NSURL URLWithString:#"............./Pharmacies.php"];
NSData * data = [NSData dataWithContentsOfURL:url];
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSMutableArray *newAnnotations = [NSMutableArray array];
CLLocationCoordinate2D location;
for (NSDictionary *dictionary in array)
{
MKPointAnnotation *newAnnotation = [[MKPointAnnotation alloc] init];
location.latitude = [dictionary[#"lat"] doubleValue];
location.longitude = [dictionary[#"lon"] doubleValue];
newAnnotation.title = dictionary[#"name"];
newAnnotation.coordinate = location;
[newAnnotations addObject:newAnnotation];
[newAnnotation release];
}
[self.MyLocation addAnnotations:newAnnotations];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString *identifier = #"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[self.MyLocation dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.pinColor = MKPinAnnotationColorPurple;
annotationView.animatesDrop = YES;
annotationView.canShowCallout = YES;
}else {
annotationView.annotation = annotation;
}
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
[self performSegueWithIdentifier:#"Details" sender:view];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Details"])
{
MKAnnotationView *annotationView = sender;
[segue.destinationViewController setAnnotation:annotationView.annotation];
}
}
Take_Photo is my detailviewcntroller.
And my storybaord look like this :
Mylocation View controller -> ( Segue: identifier ( Take_Photo )) -> Take_Photo view Controller
When I initialize the map, it shows both my location and the destination (forward geocoded from a string) but it does not draw directions between them.
Here is my code :
#import "EventDetailMapViewController.h"
#interface EventDetailMapViewController ()
#property (nonatomic,strong) MKMapItem *destination;
#end
#implementation EventDetailMapViewController
CLPlacemark *thePlacemark;
MKRoute *routeDetails;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_mapView.showsUserLocation = YES;
self.navigationController.toolbarHidden = NO;
_mapView.delegate = self;
[self getRoute];
}
- (void)addAnnotation:(CLPlacemark *)placemark {
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
point.title = [placemark.addressDictionary objectForKey:#"Street"];
point.subtitle = [placemark.addressDictionary objectForKey:#"City"];
[self.mapView addAnnotation:point];
}
-(void)showRoute:(MKDirectionsResponse *)response{
for (MKRoute *route in response.routes)
{
[_mapView
addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
for (MKRouteStep *step in route.steps){
NSLog(#"%#",step.instructions);
}
}
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
// If it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// Handle any custom annotations.
if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
// Try to dequeue an existing pin view first.
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomPinAnnotationView"];
if (!pinView)
{
// If an existing pin view was not available, create one.
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomPinAnnotationView"];
pinView.canShowCallout = YES;
} else {
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
-(void)getRoute {
[self getLocationFromString];
MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:thePlacemark];
[directionsRequest setSource:[MKMapItem mapItemForCurrentLocation]];
[directionsRequest setDestination:[[MKMapItem alloc] initWithPlacemark:placemark]];
directionsRequest.transportType = MKDirectionsTransportTypeAutomobile;
MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(#"Error %#", error.description);
} else {
routeDetails = response.routes.lastObject;
[self.mapView addOverlay:routeDetails.polyline];
}
}];
}
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
MKPolylineRenderer * routeLineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:routeDetails.polyline];
routeLineRenderer.strokeColor = [UIColor redColor];
routeLineRenderer.lineWidth = 5;
return routeLineRenderer;
}
- (IBAction)changeMapType:(id)sender {
if (_mapView.mapType == MKMapTypeStandard)
_mapView.mapType = MKMapTypeSatellite;
else
_mapView.mapType = MKMapTypeStandard;
}
-(void)getLocationFromString{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:self.agendaEntry.address completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(#"%#", error);
} else {
thePlacemark = [placemarks lastObject];
float spanX = 1.00725;
float spanY = 1.00725;
MKCoordinateRegion region;
region.center.latitude = thePlacemark.location.coordinate.latitude;
region.center.longitude = thePlacemark.location.coordinate.longitude;
region.span = MKCoordinateSpanMake(spanX, spanY);
[self.mapView setRegion:region animated:YES];
[self addAnnotation:thePlacemark];
}
}];
}
#end
I'm relatively new to this so some of this is probably wrong. What I want is when I push a button (in another view) the "agendaEntry" gets passed on the segue. It contains a string with an address, this address gets forward-geocoded and the map displays directions/routes from the user's location to the address in that string.
I don't know how to make it show driving/walking directions or to make it show multiple routes. But for starters, it would be great if it would work.
The reason it doesn't draw directions is because the directions request is being made before the destination placemark (thePlacemark) is actually set by the geocodeAddressString completion handler block.
Note what the documentation says about geocodeAddressString:completionHandler::
This method submits the specified location data to the geocoding server asynchronously and returns.
So even though getLocationFromString (which calls geocodeAddressString) is called before the directions request, execution returns and continues in getRoute immediately after the geocodeAddressString is initiated (but not completed).
Therefore, thePlacemark is still nil when getRoute sets up directionsRequest and you're probably getting an error logged such as "directions not available".
To account for this, you can move the call to the directions-request-set-up code to inside the geocodeAddressString completion handler block (after the add-annotation code).
There are three things to change for this:
In viewDidLoad, do [self getLocationFromString]; instead of [self getRoute];.
In getRoute, remove the call to getLocationFromString.
In getLocationFromString, in the completion handler block, after [self addAnnotation:thePlacemark];, do [self getRoute];.
Regarding showing multiple routes, first you'll need to actually request alternate routes (default is NO):
directionsRequest.requestsAlternateRoutes = YES;
The other part of the problem you may have experienced is due to this line in rendererForOverlay:
MKPolylineRenderer * routeLineRenderer = [[MKPolylineRenderer alloc]
initWithPolyline:routeDetails.polyline];
It's creating a polyline renderer using an external instance variable instead of the overlay parameter provided to the delegate method. This basically means the delegate method will only work for that one specific overlay (routeDetails.polyline) and since there's no control over when exactly the delegate method will be called by the map view, you can't reliably set routeDetails.polyline from outside the delegate method to be sure it points to the right overlay. Each alternate route is a separate polyline and the map view will make separate calls to rendererForOverlay for each one.
Instead, create the polyline renderer using the overlay parameter (and first check if overlay is an MKPolyline):
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:[MKPolyline class]])
{
MKPolylineRenderer * routeLineRenderer =
[[MKPolylineRenderer alloc] initWithPolyline:overlay];
routeLineRenderer.strokeColor = [UIColor redColor];
routeLineRenderer.lineWidth = 5;
return routeLineRenderer;
}
return nil;
}
Then in getRoute, instead of this:
routeDetails = response.routes.lastObject;
[self.mapView addOverlay:routeDetails.polyline];
call the showRoute method you already have which adds all the routes:
[self showRoute:response];
I'm trying to display mapview with an array of coordinates. So, i load the latitudes and longitudes from array where those are contains. It is showing perfectly. Now, i want to display one paritcular latitude & longitude with different color pin. I've referred this answer no such different i can't see.
ViewController.m
-(void)showMap:
{
...
...
DataProvider *d = [DataProvider getInstance];
NSInteger numb = sender.view.tag;
d.colorlatitude = [[arraxy objectAtIndex:numb] objectForKey:#"lat"];
d.colorlongitude = [[arraxy objectAtIndex:numb] objectForKey:#"lng"];
[d._address removeAllObjects];
[arraxy removeObjectAtIndex:sender.view.tag];
d._address = arraxy;
MapViewController *map = [[MapViewController alloc]initWithNibName:#"MapViewController" bundle:nil];
[self.navigationController pushViewController:map animated:YES];
}
MapViewController.m
-(void)viewWillAppear:(BOOL)animated
{
DataProvider *d = [DataProvider getInstance];
[_mapView removeAnnotations:_mapView.annotations];
RegisterViewController *appDelegate = [[RegisterViewController alloc]init];
[_mapView setShowsUserLocation:YES];
[_mapView setRegion:MKCoordinateRegionMakeWithDistance([appDelegate.locationManager location].coordinate, 1000, 1000)];
[_mapView setUserTrackingMode:MKUserTrackingModeNone];
MKCoordinateRegion rregion = {{0.0,0.0},{0.0,0.0}};
rregion.center.latitude = [d.colorlatitude floatValue];
rregion.center.longitude = [d.colorlongitude floatValue];
rregion.span.latitudeDelta=0.001f;
rregion.span.longitudeDelta=0.001f;
[_mapView setRegion:rregion];
MapviewAnnotations *add = [[MapviewAnnotations alloc]init];
add.coordinate = rregion.center;
[_mapView addAnnotation:add];
if (d._address)
{
for (int i=0; i<[d._address count]; i++)
{
NSDictionary *dic=[d._address objectAtIndex:i];
MKCoordinateRegion region={{0.0,0.0},{0.0,0.0}};
region.center.latitude=[[dic objectForKey:#"lat"]floatValue];
region.center.longitude=[[dic objectForKey:#"lng"]floatValue];
region.span.latitudeDelta=0.001f;
region.span.longitudeDelta=0.001f;
[_mapView setRegion:region];
MapviewAnnotations *ann=[[MapviewAnnotations alloc]init];
ann.coordinate=region.center;
[_mapView addAnnotation:ann];
}
}
[super viewWillAppear:YES];
}
and my MKMapView's delegate method is
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if (![annotation isKindOfClass:[MapviewAnnotations class]])
{
return nil;
}
static NSString *reuseId = #"currentloc";
MKPinAnnotationView *annView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (annView == nil)
{
annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
annView.animatesDrop = NO;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
}
else
{
annView.annotation = annotation;
}
DataProvider *mvAnn = [DataProvider getInstance];
if (mvAnn.colorlatitude) // here i'm checking the condition.
{
annView.pinColor = MKPinAnnotationColorGreen;
}
else
{
annView.pinColor = MKPinAnnotationColorRed;
}
return annView;
}
I'm just writting the condition if the co-ordinate is there i've to plot the green color pin to that particular coordinate only. How to achieve this?
The difference between your code and the one Hinata has referred you to is that the if statement in the other code uses a value (yesno) on the annotation it is currently drawing to decide what colour to use. You are getting a value from DataProvider but not telling it which annotation you are drawing, so the instance it gives you is just what ever the instance method feels like returning at the time the map is asking for the pin. You need to tell it what you're drawing for it to decide what to put into colorlatitude
I've done this through some flags like below inside of my - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
MapviewAnnotations *mvAnn = (MapviewAnnotations *)annotation;
if (mvAnn.flag == 1)
{
annView.pinColor = MKPinAnnotationColorGreen;
}
else if (mvAnn.flag == 10)
{
annView.pinColor = MKPinAnnotationColorPurple;
}
else
{
annView.pinColor = MKPinAnnotationColorRed;
}
In my viewWillAppear i received the coordinates from DataProvider and assigned with separate MapviewAnnotations with flags and differentiate it with three type of pins simply.
Cheers!