I have 21 different images that I am using for custom annotations on a map. When I load the map initially, everything is perfect. It is when I navigate off of the area and back in that it seems that the images change. The annotation pins no longer correspond with the correct image (however the title and subtitle are still correct when I press on the annotation). It is like the images suddenly get mixed up. By the way I am just entering test information into NSUserDefaults and using that to test the functionality of displaying the custom annotations on the map. I am assuming it has something to do with the reusability of annotation views but I cannot get my code right.
MapViewController.h
#import "ViewController.h"
#import <MapKit/MapKit.h>
#interface MapViewController : ViewController<MKMapViewDelegate>
{
NSUserDefaults *defaults;
NSMutableArray *reportedSightings;
}
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#end
MapViewController.m
#import "MapViewController.h"
#import CoreLocation;
#interface MapViewController ()<CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
#implementation MapViewController
- (void)viewDidLoad
{
[super viewDidLoad];
defaults = [NSUserDefaults standardUserDefaults];
reportedSightings = [[NSMutableArray alloc] init];
[reportedSightings addObject:#"turtle1,44.008897,-77.743073"];
[reportedSightings addObject:#"turtle2,43.997620,-77.675193"];
[reportedSightings addObject:#"turtle3,44.001554,-77.689685"];
[reportedSightings addObject:#"turtle4,43.992655,-77.712643"];
[reportedSightings addObject:#"turtle5,44.005708,-77.725666"];
[reportedSightings addObject:#"snake1,43.993950,-77.720637"];
[reportedSightings addObject:#"snake2,43.994176,-77.717224"];
[reportedSightings addObject:#"snake3,43.998308,-77.677515"];
[reportedSightings addObject:#"snake4,44.007523,-77.719716"];
[reportedSightings addObject:#"snake5,43.997320,-77.731911"];
[reportedSightings addObject:#"snake6,43.995390,-77.716450"];
[reportedSightings addObject:#"amphibian1,43.996503,-77.694154"];
[reportedSightings addObject:#"amphibian2,43.989638,-77.704582"];
[reportedSightings addObject:#"amphibian3,44.009406,-77.738130"];
[reportedSightings addObject:#"amphibian4,44.001059,-77.733429"];
[reportedSightings addObject:#"amphibian5,44.005405,-77.713410"];
[reportedSightings addObject:#"amphibian6,44.002750,-77.699245"];
[reportedSightings addObject:#"amphibian7,43.999160,-77.692886"];
[reportedSightings addObject:#"amphibian8,43.993869,-77.722742"];
[reportedSightings addObject:#"amphibian9,43.995589,-77.714681"];
[reportedSightings addObject:#"amphibian10,43.998462,-77.675608"];
[defaults setObject:reportedSightings forKey:#"reportedSightings"];
[defaults synchronize];
reportedSightings = [NSMutableArray arrayWithArray:[defaults objectForKey:#"reportedSightings"]];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
self.mapView.showsUserLocation = YES;
MKCoordinateRegion region = {{0.0, 0.0}, {0.0, 0.0}};
region.center.latitude = 43.998564;
region.center.longitude = -77.709888;
[self.mapView setRegion:region];
for(int i=0; i<reportedSightings.count; i++)
{
NSString *reportedSighting = reportedSightings[i];
NSString *speciesName = [reportedSighting substringToIndex:[reportedSighting rangeOfString:#","].location];
reportedSighting = [reportedSighting substringFromIndex:[reportedSighting rangeOfString:#","].location+1];
NSString *sightingLatitude = [reportedSighting substringToIndex:[reportedSighting rangeOfString:#","].location];
reportedSighting = [reportedSighting substringFromIndex:[reportedSighting rangeOfString:#","].location+1];
NSString *sightingLongitude = reportedSighting;
float latitude = [sightingLatitude floatValue];
float longitude = [sightingLongitude floatValue];
CLLocationCoordinate2D reportedSightingCoordinates = CLLocationCoordinate2DMake(latitude, longitude);
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = reportedSightingCoordinates;
point.title = speciesName;
point.subtitle = [NSString stringWithFormat:#"%f, %f", latitude, longitude];
[self.mapView addAnnotation:point];
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([self.mapView respondsToSelector:#selector(camera)])
{
MKMapCamera *newCamera = [[self.mapView camera] copy];
[newCamera setPitch:0.0];
[newCamera setHeading:307.197710];
[newCamera setAltitude:14515.983058];
[self.mapView setCamera:newCamera animated:YES];
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if([annotation isKindOfClass:[MKPointAnnotation class]])
{
MKAnnotationView *pinView = (MKAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:#"CustomViewAnnotation"];
if(!pinView)
{
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomViewAnnotation"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#Annotation", [annotation title]]];
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
#end
For this section:
if(!pinView)
{
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomViewAnnotation"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#Annotation", [annotation title]]];
}
else
{
pinView.annotation = annotation;
}
Add the line:
pinView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#Annotation", [annotation title]]];
Also for the else, so it will look like that:
if(!pinView)
{
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"CustomViewAnnotation"];
pinView.canShowCallout = YES;
pinView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#Annotation", [annotation title]]];
}
else
{
pinView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#Annotation", [annotation title]]];
pinView.annotation = annotation;
}
Related
i am working on a map kit that shows all the data extracted from an xml web service .this web service contains 3 variables longitude (lon),latitude(lat), the name of the atm (atmName).the for loop is extracting the data from the Aatm array but the pins are not showing on the map .also my pins are all from the same region thats why i used a default center from the Aatm array with a default value. here is my code
thank you for helping me in advance :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Aatm = [[NSMutableArray alloc] init];
pinArray = [[NSMutableArray alloc] init];
NSString *url=#"http://192.168.83.1:8080/jeeRestApp-1.0/rest/Atm";
NSXMLParser *parser;
parser=[[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
parser.delegate=self;
if ([parser parse]==FALSE){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Erreur" message:#"erreur de connection!" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[alert show];
}
//Setting the approximate region
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.mapview setShowsUserLocation:YES];
MKCoordinateRegion Myregion;
CLLocationCoordinate2D center1;
//replace by variable -----------------------------------
atm=[Aatm objectAtIndex:1];
center1.latitude=[atm.lat doubleValue];
center1.longitude=[atm.lon doubleValue];
NSLog(#"la latitude (defaut) est: %#",atm.lat);
MKCoordinateSpan span1;
span1.longitudeDelta = 0.01f;
span1.latitudeDelta = 0.01f;
Myregion.center=center1;
Myregion.span=span1;
[mapview setRegion:Myregion animated:YES];
for(int i = 0; i<=[Aatm count] - 1;i++)
{
//CLLocationCoordinate2D newCoord = { atm.lat, atm.lon};
atm=[Aatm objectAtIndex:i];
CLLocationCoordinate2D pinLocaton;
pinLocaton.latitude=[atm.lat doubleValue];
NSLog(#"latitude est de :%#",atm.lat);
pinLocaton.longitude=[atm.lon doubleValue];
NSLog(#"longitude est de :%#",atm.lon);
MKPointAnnotation *annotation=[MKPointAnnotation alloc];
annotation.title=atm.atmName;
NSLog(#"latitude est de :%#",atm.atmName);
annotation.coordinate=pinLocaton;
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotation1"];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = NO;
[newAnnotation setSelected:YES animated:YES];
[mapview addAnnotation:annotation];
NSLog(#"annotation added");
}
You need to implement mapView:viewForAnnotation: something like:
-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MKPointAnnotation class]])
{
MKPinAnnotationView* view = (MKPinAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
if(!view)
{
view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pin"];
}
else
{
view.annotation = annotation;
}
view.pinColor = MKPinAnnotationColorGreen;
view.animatesDrop = YES;
view.canShowCallout = NO;
return view;
}
else
{
return nil;
}
}
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
I'm looking to adapt the following tutorial to create annotations from a plist. I'm brand new to Objective C and Xcode, and tried many different tutorials but can't seem to get this together.
Annotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface Annotation : NSObject <MKAnnotation>
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString * title;
#property (nonatomic, copy) NSString * subtitle;
#property (nonatomic, copy) UIImageView * leftCalloutAccessoryView;
#end
Annotation.m
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle, leftCalloutAccessoryView;
#end
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet MKMapView *myMapView;
#end
ViewController.m
#import "ViewController.h"
#import "Annotation.h"
#interface ViewController ()
#end
//Wimbledon Coordinates
#define WIMB_LATITUDE 51.434783;
#define WIMB_LONGITUDE -0.213428;
//Stadium Coordinates
#define ARSENAL_LATITUDE 51.556899;
#define ARSENAL_LONGITUDE -0.106403;
#define CHELSEA_LATITUDE 51.481314;
#define CHELSEA_LONGITUDE -0.190129;
//Span
#define THE_SPAN 0.10f;
#implementation ViewController
#synthesize myMapView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Create the region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = ARSENAL_LATITUDE;
center.longitude = ARSENAL_LONGITUDE;
//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span=span;
//Set our mapView
[myMapView setRegion:myRegion animated:YES];
//Annotation
NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Annotation * myAnn;
//Arsenal Annotation
myAnn = [[Annotation alloc] init];
location.latitude = ARSENAL_LATITUDE;
location.longitude = ARSENAL_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Arsenal FC";
myAnn.subtitle = #"The Gunners";
//myAnn.image = [UIImage imageNamed:#"location.png"];
[locations addObject:myAnn];
//Chelsea Annotation
myAnn = [[Annotation alloc] init];
location.latitude = CHELSEA_LATITUDE;
location.longitude = CHELSEA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Chelsea FC";
myAnn.subtitle = #"The Blue Lions";
[locations addObject:myAnn];
[self.myMapView addAnnotations:locations];
}
//THIS CODE WORKS FOR CUSTOM ANNOTATIONS
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"redpin"];
newAnnotation.pinColor = MKPinAnnotationColorRed;
UIImageView *IconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"marker.png"]];
newAnnotation.leftCalloutAccessoryView = IconView;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Got it to work thanks to a suggestion above. Also added in custom markers and a left icon to call out. I commented out the old coordinate code and the annotation red pins with left icon.
Hope this helps others who might've gone crazy searching for a solution as I have.
Stadiums.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Stadiums</key>
<array>
<dict>
<key>Title</key>
<string>Arsenal</string>
<key>Subtitle</key>
<string>The Gunners</string>
<key>Latitude</key>
<string>51.556899</string>
<key>Longitude</key>
<string>-0.106403</string>
</dict>
<dict>
<key>Title</key>
<string>Chelsea</string>
<key>Subtitle</key>
<string>The Blue Lions</string>
<key>Latitude</key>
<string>51.481314</string>
<key>Longitude</key>
<string>-0.190129</string>
</dict>
</array>
</dict>
</plist>
ViewController.m
#import "ViewController.h"
#import "Annotation.h"
#interface ViewController ()
#end
//Wimbledon Coordinates
#define WIMB_LATITUDE 51.434783;
#define WIMB_LONGITUDE -0.213428;
//Stadium Coordinates
#define ARSENAL_LATITUDE 51.556899;
#define ARSENAL_LONGITUDE -0.106403;
#define CHELSEA_LATITUDE 51.481314;
#define CHELSEA_LONGITUDE -0.190129;
//Span
#define THE_SPAN 0.10f;
#implementation ViewController
#synthesize myMapView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Create the region
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = ARSENAL_LATITUDE;
center.longitude = ARSENAL_LONGITUDE;
//Span
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span=span;
//Set our mapView
[myMapView setRegion:myRegion animated:YES];
/*
//Annotation
NSMutableArray * locations = [[NSMutableArray alloc] init];
CLLocationCoordinate2D location;
Annotation * myAnn;
//Arsenal Annotation
myAnn = [[Annotation alloc] init];
location.latitude = ARSENAL_LATITUDE;
location.longitude = ARSENAL_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Arsenal FC";
myAnn.subtitle = #"The Gunners";
//myAnn.image = [UIImage imageNamed:#"location.png"];
[locations addObject:myAnn];
//Chelsea Annotation
myAnn = [[Annotation alloc] init];
location.latitude = CHELSEA_LATITUDE;
location.longitude = CHELSEA_LONGITUDE;
myAnn.coordinate = location;
myAnn.title = #"Chelsea FC";
myAnn.subtitle = #"The Blue Lions";
[locations addObject:myAnn];
[self.myMapView addAnnotations:locations];
*/
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Stadiums" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSArray *anns = [dict objectForKey:#"Stadiums"];
NSLog(#"read1");
for(int i = 0; i < [anns count]; i++) {
NSLog(#"read2");
float realLatitude = [[[anns objectAtIndex:i] objectForKey:#"Latitude"] floatValue];
float realLongitude = [[[anns objectAtIndex:i] objectForKey:#"Longitude"] floatValue];
NSLog(#"read3");
Annotation *myAnnotation = [[Annotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate = theCoordinate;
myAnnotation.title = [[anns objectAtIndex:i] objectForKey:#"Title"];
myAnnotation.subtitle = [[anns objectAtIndex:i] objectForKey:#"Subtitle"];
[myMapView addAnnotation:myAnnotation];
[annotations addObject:myAnnotation];
//[myAnnotation release];
}
}
//THIS CODE WORKS FOR CUSTOM ANNOTATIONS
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[myMapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
}
//Custom Pin
annotationView.image = [UIImage imageNamed:#"toilets.png"];
//Custom Thumbnail (left side)
UIImageView *IconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"toilets.png"]];
annotationView.leftCalloutAccessoryView = IconView;
annotationView.canShowCallout = YES;
annotationView.annotation = annotation;
return annotationView;
/*
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"redpin"];
newAnnotation.pinColor = MKPinAnnotationColorRed;
UIImageView *ThumbView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"toilets.png"]];
newAnnotation.leftCalloutAccessoryView = ThumbView;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
*/
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Personally, I would use CoreData to store the annotations. However, if you are stuck on writing things to disk, I would make your annotation object implement the NSCoding protocol and use NSKeyedArchiver to save and load your objects.
+ (NSObject *)readArchiveFile:(NSString *)inFileName
{
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectoryPath, inFileName];
NSObject *returnObject = nil;
if( [fileMgr fileExistsAtPath:filePath] )
{
#try
{
returnObject = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
}
#catch (NSException *exception)
{
[FileUtils deleteFile:inFileName];
returnObject = nil;
}
}
return returnObject;
}
+ (void)archiveFile:(NSString *)inFileName inObject:(NSObject *)inObject
{
NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectoryPath, inFileName];
#try
{
BOOL didSucceed = [NSKeyedArchiver archiveRootObject:inObject toFile:filePath];
if( !didSucceed )
{
NSLog(#"File %# write operation %#", inFileName, didSucceed ? #"success" : #"error" );
}
}
#catch (NSException *exception)
{
NSLog(#"File %# write operation threw an exception:%#", filePath, exception.reason);
}
}
I have a mkmapview that I'm dropping several placemark pins on, however I've not been able to get the pins to show the correct title on the callouts, seems to randomly show a title from the collection of pins on the map. Any ideas? Code looks like:
(void)viewDidLoad {
[super viewDidLoad];
[mapView setDelegate:self];
CLLocationCoordinate2D geos = CLLocationCoordinate2DMake([putInLat doubleValue], [putInLong doubleValue]);
aMarker = [[RNPlaceMark alloc] initWithCoordinate:geos Title:#"Location A"];
CLLocationCoordinate2D geos2 = CLLocationCoordinate2DMake([takeOutLat doubleValue], [takeOutLong doubleValue]);
bMarker = [[RNPlaceMark alloc] initWithCoordinate:geos2 Title:#"Location B"];
NSArray *annots = [[NSArray alloc] initWithObjects:putInMarker, takeOutMarker, nil];
[mapView addAnnotations:annots];
}
and
(MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id<MKAnnotation>)annotation {
NSString *title = annotation.title;
MKPinAnnotationView *pinView=(MKPinAnnotationView *)[aMapView dequeueReusableAnnotationViewWithIdentifier:title];
if(pinView==nil)
pinView=[[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:title] autorelease];
if(annotation == aMarker)
[pinView setPinColor:MKPinAnnotationColorGreen];
else if(annotation == bMarker)
[pinView setPinColor:MKPinAnnotationColorRed];
pinView.canShowCallout=YES;
pinView.animatesDrop=YES;
return pinView;
}
I switched the code to use MKPointAnnotation it worked fine, so now it looks like...
I'm executing the following code in my viewDidLoad method on the view that host the UIMapVIew:
MKPointAnnotation *myMarker = [[MKPointAnnotation alloc] init];
[myMarker setTitle:#"Hello World"];
CLLocationCoordinate2D geos = CLLocationCoordinate2DMake([myMarkerLat doubleValue], [myMarkerLong doubleValue]);
[myMarker setCoordinate:geos];
NSArray *annots = [[NSArray alloc] initWithObjects:myMarker, nil];
[mapView addAnnotations:annots];
then I have...
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id
<MKAnnotation>)annotation
{
NSString *title = annotation.title;
MKPinAnnotationView *pinView=(MKPinAnnotationView *)[aMapView dequeueReusableAnnotationViewWithIdentifier:title];
if(pinView==nil)
pinView=[[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:title] autorelease];
//If you want to change the color of the pin you can with something like...
//if(annotation == whatEverInstanceOfAMarkerIWantToKeep)
// [pinView setPinColor:MKPinAnnotationColorGreen];
pinView.canShowCallout=YES;
pinView.animatesDrop=YES;
return pinView;
}
I added a plist database to store information for annotations in a MKMapView. Once I implemented the code to grab the information, my delegate methods are no longer being called.
The code I added was:
- (void)viewDidLoad
{
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSString *path = [[NSBundle mainBundle] pathForResource:#"MillersStores" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSArray *anns = [dict objectForKey:#"Root"];
for(int i = 0; i < [anns count]; i++) {
float realLatitude = [[[anns objectAtIndex:i] objectForKey:#"Latitude"] floatValue];
float realLongitude = [[[anns objectAtIndex:i] objectForKey:#"Longitude"] floatValue];
MillersLocations *myAnnotation = [[MillersLocations alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate = theCoordinate;
myAnnotation.title = [[anns objectAtIndex:i] objectForKey:#"Title"];
myAnnotation.subtitle = [[anns objectAtIndex:i] objectForKey:#"Address"];
[mapView addAnnotation:myAnnotation];
[annotations addObject:myAnnotation];
[myAnnotation release];
}
}
And this is one of delegate method that's no longer being called is:
- (MKAnnotationView *) mapView:(MKMapView *) mapView viewForAnnotation:(id ) annotation {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKPinAnnotationView *pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil] autorelease];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIImageView *leftIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"MillersAnnotation.png"]];
pinView.leftCalloutAccessoryView = leftIconView;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
return pinView;
}
I have another delegate method in there that also zooms into the User's Location that's not being called either, as well as the calloutAccessoryControlTapped method that's no longer being called.
I know it has something to do with the new code, but I'm confused as to how to even debug this because it's not giving me errors and I can't log it because the entire methods aren't even being called. When I get rid of the new code, the old code works fine...What is it in the new code that negates the old code?
It sounds like the map view's delegate property is not set.
Did the old code contain this line:
mapView.delegate = self;
Add that to viewDidLoad or, in IB, connect the map view's delegate outlet to File's Owner.