Pins have disappeared when using MKAnnotationView delegate - ios

My MKAnnotationView delegate method is been called as I can see my NSLog output. However the pins are not appearing on the map. Is there something I'm missing here?
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *nearbyMapView;
#end
MapViewController.m
#import "MapViewController.h"
#import "AppDelegate.h"
#interface MapViewController ()
#end
#implementation MapViewController
AppDelegate *appDelegate;
- (void)viewDidLoad
{
[super viewDidLoad];
appDelegate=[[UIApplication sharedApplication] delegate];
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(54.995184, -1.566699);
MKCoordinateSpan span = MKCoordinateSpanMake(0.5, 0.5);
MKCoordinateRegion regionToDisplay = MKCoordinateRegionMake(center, span);
[self.nearbyMapView setRegion: regionToDisplay];
for (int i = 0; i < [[appDelegate offersFeeds] count]; i++) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
NSString *plotAddress = [[[appDelegate offersFeeds] objectAtIndex:i] valueForKey:#"addressline"];
NSString *plotTitle = [[[appDelegate offersFeeds] objectAtIndex:i] valueForKey:#"title"];
[geocoder geocodeAddressString:plotAddress completionHandler:^(NSArray *placemarks, NSError *error) {
if (placemarks && placemarks.count > 0)
{
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc]initWithPlacemark:topResult];
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = placemark.location.coordinate;
pa.title = plotTitle;
[self.nearbyMapView addAnnotation:pa];
}
}];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *pinView = nil;
static NSString *defaultPinID = #"identifier";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil ) {
NSLog(#"Inside IF");
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
pinView.enabled = YES;
pinView.canShowCallout = YES;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//Accessoryview for the annotation view in ios.
pinView.rightCalloutAccessoryView = btn;
}
else {
pinView.annotation = annotation;
}
pinView.annotation = annotation;
return pinView;
}
#end

In viewForAnnotation, the code is creating an MKAnnotationView but not setting an image for it. There is no default image on an MKAnnotationView so the annotations are invisible.
When you don't implement the delegate at all, the map view creates MKPinAnnotationViews for you with a red pin color. MKPinAnnotationView is a convenient subclass of MKAnnotationView which supplies a pin image (in one of three colors).
When you implement the delegate, it's up to you to create the right view and set the properties as needed.
Either create an MKPinAnnotationView instead (which provides a default pin image) or set the image property on the plain MKAnnotationView.
To use MKPinAnnotationView:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = nil;
static NSString *defaultPinID = #"identifier";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
{
NSLog(#"Inside IF");
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
pinView.pinColor = MKPinAnnotationColorRed; //or Green or Purple
pinView.enabled = YES;
pinView.canShowCallout = YES;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//Accessoryview for the annotation view in ios.
pinView.rightCalloutAccessoryView = btn;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
or to use MKAnnotationView and your own image:
//same code as the current but add this line
//after the initWithAnnotation:
pinView.image = [UIImage imageNamed:#"SomeImage.png"];

Related

custom annotation is not appearing without setting image

I am trying to create custom annotation as each annotation save some data which i need to show on tap of pin. But i need to show default ios pin image. Everything is working fine but pin will only show when i set any image. without setting image it is not showing default ios pin. My code is
CustomAnnotation.h file
#interface CustomAnnotation : NSObject<MKAnnotation>
#property(nonatomic,strong)NSString *title;
#property(nonatomic,strong)NSString *subTitle;
#property(nonatomic)CLLocationCoordinate2D coordinate;
#property(nonatomic,strong) UserDevice *userData;
-(instancetype)initWithUserData:(UserDevice *)userData;
on mapViewC.h
-(void)addMarkersOnMap{
for (UserDevice* userDevice in markersArray) {
CustomAnnotation *point = [[CustomAnnotation alloc]initWithUserData:userDevice];
point.coordinate = CLLocationCoordinate2DMake(userDevice.latitude, userDevice.longitude);
point.userData = userDevice;
point.title = #"dszf";
[mapview addAnnotation:point];
MKMapRect mapRect = [self getZoomingRectOnMap:mapview toFitAllOverlays:YES andAnnotations:YES includeUserLocation:NO];
[mapview setVisibleMapRect:mapRect edgePadding:UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0) animated:YES];
}
}
#pragma mark - MKMapView Delegate methods
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *customAnnotation = annotation;
MKAnnotationView *customAnnotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"annotationViewID"];
if (customAnnotationView == nil){
customAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotationViewID"];
}
// customAnnotationView.image = [UIImage imageNamed:#"pin-1"];
customAnnotationView.canShowCallout = true;
customAnnotationView.annotation = customAnnotation;
return customAnnotationView;
}
return nil;
}
Instead of CustomAnnotationView use MKPinAnnotationView in your viewForAnnotation MKMapViewDelegate method
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *customAnnotation = annotation;
MKPinAnnotationView *customAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"annotationViewID"];
if (customAnnotationView == nil){
customAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotationViewID"];
}
// customAnnotationView.image = [UIImage imageNamed:#"pin-1"];
customAnnotationView.canShowCallout = true;
customAnnotationView.annotation = customAnnotation;
return customAnnotationView;
}
return nil;
}
Hope this helps
CustomAnnotation *customAnnotation = annotation;
NSString *annotationIdentifier = #"PinViewAnnotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier: annotationIdentifier];
if (pinView ==nil) {
pinView = [[MKPinAnnotationView alloc]initWithAnnotation: customAnnotation reuseIdentifier: annotationIdentifier];
}
pinView.pinColor = MKPinAnnotationColorGreen; // change color
pinView.canShowCallout = YES;
pinView.enabled = YES;
mapView selectAnnotation:pinView animated:YES];

Custom MKAnnotationView Showing Wrong Image

I have an MKMapView where I want to display annotations of contacts' faces. I looked at Apple's sample app MapCallouts and have so far written this:
Annotation.h
#interface Annotation : NSObject <MKAnnotation>
#property (nonatomic, strong) UIImage *image;
#property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
+ (MKAnnotationView *)createViewAnnotationForMapView:(MKMapView *)mapView annotation:(id <MKAnnotation>)annotation;
#end
Annotation.m
#import "CustomAnnotationView.h"
#implementation Annotation
+ (MKAnnotationView *)createViewAnnotationForMapView:(MKMapView *)mapView annotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *returnedAnnotationView =
(CustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"Annotation"];
if (returnedAnnotationView == nil)
{
returnedAnnotationView =
[[CustomAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"Annotation"];
}
return returnedAnnotationView;
}
#end
CustomAnnotationView.h
#interface CustomAnnotationView : MKAnnotationView
CustomAnnotationView.m
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:#"Annotation"];
if (self != nil)
{
Annotation *mapItem = (Annotation *)self.annotation;
// Create imageView and labels, etc.
}
return self;
}
Then, to drop my annotation, I have this method which loops through an array of contacts, gets their address, finds the CLLOcationCoordinate2D, and creates an Annotation.
-(void)sortContacts{
for (APContact *contact in self.peopleArray){
[operationQueue addOperationWithBlock:^{
NSString *addressString = // get address from contact;
contact.addressString = addressString;
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:addressString
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0 && !error) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
CLLocation *location = topResult.location;
CLLocationCoordinate2D coordinate = location.coordinate;
Annotation *annotation = [[Annotation alloc] init];
annotation.image = [UIImage imageNamed:#"Annotation"];
if (contact.thumbnail.size.width > 0){
annotation.image = contact.thumbnail;
}
else{
annotation.image = [UIImage imageNamed:#"Annotation"];
}
annotation.coordinate = coordinate;
[self.mapView addAnnotation:annotation];
}
else if (error){
NSLog(#"ERROR");
}
}
];
}];
}
}
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
CustomAnnotationView *returnedAnnotationView = nil;
if ([annotation isKindOfClass:[Annotation class]])
{
returnedAnnotationView = (CustomAnnotationView *)[Annotation createViewAnnotationForMapView:self.mapView annotation:annotation];
}
return returnedAnnotationView;
}
However, when I scroll across self.mapView, the incorrect contact images are showing for the wrong annotations. I'm not sure how to fix this. Any help would be much appreciated. Thanks
I added a property to my custom annotation view and simply changed the image everytime I dequeued or created a new annotation.
#property (nonatomic, strong) UIImageView *annotationImage;

Building MapView Annotations is very slow

I have an application which shows something around 100 Annotations (with custom pin-images, callout accessories and annotation-images) in a MapView. While building the annotations I store a link between annotation and building so I can assign the right building and open the right segue afterwards.
In iOS 6 they get built really fast, I also enabled animation while adding them, so one pin got dropped after the other, but with apple maps in iOS7 this isn't possible anymore (?). Now building those 100 annotations takes over 1 second on my iPhone 4S and that's too long. Is there anyway to improve the code?
- (void)viewDidLoad
...
//creating annotations
annotationlink = [[NSMutableArray alloc] init];
for (int i = 0; i < data.count; i++) {
NSDictionary *dataItem = [data objectAtIndex:i];
//storing annotation in array for link
Annotation *buildingannotation = [[Annotation alloc] init];
NSNumber *index = [NSNumber numberWithInteger:i];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:index, indexKey, buildingannotation, annotationKey, nil];
[annotationlink addObject:dict];
buildingannotation.title = [dataItem objectForKey:#"Building"];
buildingannotation.subtitle = [dataItem objectForKey:#"Info"];
MKCoordinateRegion buildingcoordinates;
buildingcoordinates.center.latitude = [[dataItem objectForKey:#"Latitude"] floatValue];
buildingcoordinates.center.longitude = [[dataItem objectForKey:#"Longitude"] floatValue];
buildingannotation.coordinate = buildingcoordinates.center;
[self.mapView addAnnotation:buildingannotation];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
MKAnnotationView *pinView = (MKAnnotationView *)
[self.mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];
MKAnnotationView *customAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
customAnnotationView.canShowCallout = YES;
//right button to detail view
UIButton* disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
customAnnotationView.rightCalloutAccessoryView = disclosureButton;
//left button for image
NSInteger *buildingindex = [self getIndex:annotation];
NSDictionary *dataItem = [data objectAtIndex:buildingindex];
NSString* filename = [dataItem objectForKey:#"Thumb"];
filename = [filename stringByAppendingString:#"#2x.jpg"];
NSString* resourceimagePath = [resourcePath stringByAppendingPathComponent:filename];
Image = [UIImage imageWithContentsOfFile:resourceimagePath];
UIImageView *AnnotationThumb = [[UIImageView alloc] initWithImage:Image];
AnnotationThumb.frame = CGRectMake(0, 0, 31, 31);
customAnnotationView.leftCalloutAccessoryView = AnnotationThumb;
//annotation image
customAnnotationView.image = [UIImage imageNamed:#"Annotation_white.png"];
return customAnnotationView;
return pinView;
}
the following function gets the index of the current annotation using nspredicate to filter the array with the dictionaries. the advantage of this is the fact, that i can also use it when calloutAccessoryControlTapped:
-(NSInteger*) getIndex:(Annotation*)searchannotation
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K == %#", annotationKey, searchannotation];
NSArray *filteredarray = [annotationlink filteredArrayUsingPredicate:predicate];
NSDictionary *building = [filteredarray objectAtIndex:0];
NSInteger *buildingIndex = [[building objectForKey:indexKey] integerValue];
return buildingIndex;
}
With an iPhone 4S the last pin is built 1.14 seconds after the view gets loaded.
if i search the annotation link array manually instead of using nspredicate function like this:
//left button for image
int buildingIndex;
for (int i = 0; i < annotationlink.count; i++) {
NSDictionary *annotationDict = [annotationlink objectAtIndex:i];
if ([[annotationDict objectForKey:annotationKey] isEqual:annotation]) {
buildingIndex= [[annotationDict objectForKey:indexKey] integerValue];
i = annotationlink.count;
}
}
NSDictionary *dataItem = [data objectAtIndex:buildingIndex];
the log says that the last pin is built 1.89 seconds after the viewDidLoad.
if i create the annotations in viewDidApper instead of viewDidLoad the View is shown off course immediately but the background takes some time to load so until the pins are dropped everything is gray which is also not very nice...
Thank you Anna for your suggestions! I implemented the improvements like this:
Annotation.h:
#import <MapKit/MKAnnotation.h>
#interface Annotation : NSObject <MKAnnotation> {}
#property(nonatomic, assign) CLLocationCoordinate2D coordinate;
#property(nonatomic, copy) NSString *title;
#property(nonatomic, copy) NSString *subtitle;
#property NSInteger *ID;
#end
Annotation.m:
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle, ID;
#end
ViewDidAppear:
//creating annotations
for (int i = 0; i < data.count; i++) {
NSDictionary *dataItem = [data objectAtIndex:i];
Annotation *buildingannotation = [[Annotation alloc] init];
buildingannotation.ID = i;
buildingannotation.title = [dataItem objectForKey:#"Building"];
buildingannotation.subtitle = [dataItem objectForKey:#"Subtitle"];
MKCoordinateRegion buildingcoordinates;
buildingcoordinates.center.latitude = [[dataItem objectForKey:#"Latitude"] floatValue];
buildingcoordinates.center.longitude = [[dataItem objectForKey:#"Longitude"] floatValue];
buildingannotation.coordinate = buildingcoordinates.center;
[self.mapView addAnnotation:buildingannotation];
}
viewForAnnotation:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
MKAnnotationView *pinView = (MKAnnotationView *)
[self.mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];
if (pinView == nil) {
MKAnnotationView *customAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
customAnnotationView.canShowCallout = YES;
//right button to detail view
UIButton* disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
customAnnotationView.rightCalloutAccessoryView = disclosureButton;
//left button for image
Annotation *buildingAnnotation = (Annotation *)annotation;
NSInteger *buildingindex = buildingAnnotation.ID;
NSString *filePath = [thumbname objectAtIndex:buildingindex];
UIImageView *AnnotationThumb = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filePath]];
AnnotationThumb.frame = CGRectMake(0, 0, 31, 31);
customAnnotationView.leftCalloutAccessoryView = AnnotationThumb;
//annotation image
customAnnotationView.image = [UIImage imageNamed:#"Annotation_white.png"];
return customAnnotationView;
} else {
pinView.annotation = annotation;
}
return pinView;
}
Callout:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
Annotation *buildingAnnotation = (Annotation *)view.annotation;
selectedbuilding = buildingAnnotation.ID;
[self performSegueWithIdentifier:#"DetailViewController" sender:self];
}
Takes still some time for showing all Annotations. Is there any chance to further improve the code?
I updated the vievForAnnotation function regarding to Anna's reply and the PhotosByLocation Sample Application. It works now and I hope it's the correct way to implement the reuse...
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
MKAnnotationView *buildingAnnotationView = (MKAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier];
if (buildingAnnotationView) {
[buildingAnnotationView prepareForReuse];
} else {
buildingAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier];
buildingAnnotationView.canShowCallout = YES;
//right button to detail view
UIButton* disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
buildingAnnotationView.rightCalloutAccessoryView = disclosureButton;
//annotation image
buildingAnnotationView.image = [UIImage imageNamed:#"Annotation_white.png"];
}
//left button for image
Annotation *buildingAnnotation = (Annotation *)annotation;
NSInteger *buildingindex = buildingAnnotation.ID;
NSString *filePath = [thumbname objectAtIndex:buildingindex];
UIImageView *AnnotationThumb = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filePath]];
AnnotationThumb.frame = CGRectMake(0, 0, 31, 31);
buildingAnnotationView.leftCalloutAccessoryView = AnnotationThumb;
return buildingAnnotationView;
}

How to add an UIButton to placemark? ios objective c

How do I add a button to my placemarks and then get it to push onto a view controller?
- (void)viewDidLoad
{
[super viewDidLoad];
// Set "More" logo in navigation bar
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Navigation"]];
appDelegate=[[UIApplication sharedApplication] delegate];
// Set longatude and latitude to tyne and wear
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(54.995184, -1.566699);
// Set span to cover area
MKCoordinateSpan span = MKCoordinateSpanMake(0.5, 0.5);
// Set region
MKCoordinateRegion regionToDisplay = MKCoordinateRegionMake(center, span);
[self.nearbyMapView setRegion: regionToDisplay];
for (int i = 0; i < [[appDelegate offersFeeds] count]; i++)
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
NSString *plotAddress = [[[appDelegate offersFeeds] objectAtIndex:i] valueForKey:#"addressline"];
NSString *plotTitle = [[[appDelegate offersFeeds] objectAtIndex:i] valueForKey:#"title"];
[geocoder geocodeAddressString:plotAddress completionHandler:^(NSArray *placemarks, NSError *error) {
if (placemarks && placemarks.count > 0)
{
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc]initWithPlacemark:topResult];
// Set title
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = placemark.location.coordinate;
pa.title = plotTitle;
// Add placemark to map
[self.nearbyMapView addAnnotation:pa];
}
}];
}
}
I've had a look at MKAnotationView but struggling to understand how to get this working with CLPlacemark.
Add this before you add mapview to self.view
-(void)viewDidLoad
{
MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
annotation.coordinate = yourCoordinate;
annotation.title = #"Title";
annotation.subtitle = #"SubTitle";
[mapView1 addAnnotation:annotation];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *pinView = nil;
static NSString *defaultPinID = #"identifier";
pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinView == nil )
{
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];
annotationView.enabled = YES;
pinView.canShowCallout = YES;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//Accessoryview for the annotation view in ios.
pinView.rightCalloutAccessoryView = btn;
}
else
{
pinView.annotation = annotation;
}
pinView.annotation = annotation;
return pinView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//Put your button stuff here...
}
I hope it is useful to you

MKAnnotationView - Set two different Pin colours

I'm using Parse.com as a backend and i want to show Geopoints on my map.
Every Geopoint is also connected with a database boolean field true or false.
How can I show a green pins colour for the "true" gepoint and red pins for the "false" Geopoint?
Here is code for the MapViewController.m
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
I have a function to perform the query against the parse.com database to return me all location data. It is called within the viewDidLoad Method.
- (void)viewDidLoad
{
[super viewDidLoad];
[self getAllStations];
}
Then I set the annotationView like this:
#pragma mark - MapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)geoPointAnnotation {
static NSString *MapViewAnnotationIdentifier = #"Places";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:MapViewAnnotationIdentifier];
if (geoPointAnnotation == mapView.userLocation) {
return nil;
} else {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:geoPointAnnotation reuseIdentifier:MapViewAnnotationIdentifier];
annotationView.pinColor = MKPinAnnotationColorGreen;
annotationView.canShowCallout = YES;
annotationView.draggable = YES;
annotationView.animatesDrop = YES;
}
return annotationView;
}
Here is the Code for the MapViewAnnotation.m (Object):
#import "MapViewAnnotation.h"
#import "Parse/Parse.h"
#interface MapViewAnnotation ()
#property (nonatomic, strong) PFObject *object;
#end
#implementation MapViewAnnotation
#pragma mark - Initialization
- (id)initWithObject:(PFObject *)aObject {
self = [super init];
if (self) {
_object = aObject;
PFGeoPoint *geoPoint = self.object[#"location"];
[self setGeoPoint:geoPoint]; }
return self;
}
- (void)setGeoPoint:(PFGeoPoint *)geoPoint {
_coordinate = CLLocationCoordinate2DMake(geoPoint.latitude, geoPoint.longitude);
NSString *streetName = self.object[#"adress"];
_title = [NSString stringWithFormat:#"%#", [_object objectForKey:#"name"]];
[PFGeoPoint geoPointForCurrentLocationInBackground:^(PFGeoPoint *currentLocationGeoPoint, NSError *error) { //Get current Location
if (!error) {
PFGeoPoint *distanceGeoPoint = [_object objectForKey:#"location"];
double distanceDouble = [currentLocationGeoPoint distanceInKilometersTo:distanceGeoPoint];
//NSLog(#"Distance: %.1f",distanceDouble);
_subtitle = [NSString stringWithFormat:#"%# - Distance: %.1f km", streetName, distanceDouble];
}
}];
}
#end
Can anyone give me a hint how I can show green and red pins based on a boolean?
Thanks in advance!
You can customize the pin annotation view,
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
MKAnnotationView *flagAnnotationView =
[self.mapView dequeueReusableAnnotationViewWithIdentifier:SFAnnotationIdentifier];
if (flagAnnotationView == nil)
{
MKPinAnnotationView *customPinView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:SFAnnotationIdentifier];
if(annotation.coordinate.latitude==42.0000 && annotation.coordinate.longitude==-87.65000)
//you have to keep the latitude and longitude of the pins to which you can set the colour of the pin according to that latlong
customPinView.pinColor = MKPinAnnotationColorGreen;
else
customPinView.pinColor = MKPinAnnotationColorRed;
customPinView.animatesDrop = YES;
customPinView.canShowCallout = YES;
return customPinView;
}
else
{
flagAnnotationView.annotation = annotation;
}
return flagAnnotationView;
return nil;
}
in your annotation.h file declare a nsstring as below
#property (strong , nonatomic)NSString *pinColour;
and in the implemention file do the below to check for the colour
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation{
//other code above
if ([[annotation pinColour] isEqualToString:#"Red"]) {
annotationView.pinColor = MKPinAnnotationColorRed;
}else{
annotationView.pinColor = MKPinAnnotationColorGreen;
}
}
and inside the for loop of parse, tag the relevant with to pass wither colour
annotation.pinColour = #"Red";
Can anyone give me a hint how I can show green and red pins based on a boolean?
BOOL colorRed = YES;
if (colorRed) annotationView.pinColor = MKPinAnnotationColorRed;
else annotationView.pinColor = MKPinAnnotationColorGreen;
Is that what you mean?

Resources