Hi everyone,
I am currently creating a data logging application that utilises a MapView, and a TableView at present (further expansion in due course).
The problem I currently have is creating a detail view when a user taps on the annotation disclosure button.
I am able to intercept the disclosure tap. The problem is sending the ManagedObject of the map annotation into the new MapDetailView. I have done this from TableView's as they have an index pointer to set and pass the ManagedObject into the new view, but am unable to do the same from the MapView.
The following code is what I am using to read the annotation co-ordinates from my CoreData store: -
Code:
- (void)plotMapAnnotations {
double minLat = self.mapView.region.center.latitude - (self.mapView.region.span.latitudeDelta / 2);
double maxLat = self.mapView.region.center.latitude + (self.mapView.region.span.latitudeDelta / 2);
double minLon = self.mapView.region.center.longitude - (self.mapView.region.span.longitudeDelta / 2);
double maxLon = self.mapView.region.center.longitude + (self.mapView.region.span.longitudeDelta / 2);
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity"
inManagedObjectContext:context];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(locationLat > %f AND locationLat < %f) AND (locationLong > %f AND locationLong < %f)",minLat,maxLat,minLon,maxLon];
[fetchRequest setFetchLimit:100];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (id annotation in self.mapView.annotations) {
if (![annotation isKindOfClass:[MKUserLocation class]]){
[self.mapView removeAnnotation:annotation];
}
}
[mapView removeOverlays:[mapView overlays]];
for (MapAnnotations *detailInfo in fetchedObjects) {
CLLocationCoordinate2D theCoordinate1;
theCoordinate1.latitude = detailInfo.locationLat.doubleValue;
theCoordinate1.longitude = detailInfo.locationLong.doubleValue;
MapAnnotations *annotation = [[MapAnnotations alloc] initWithName:detailInfo.locationTitle locationType:detailInfo.locationType locationID:detailInfo.locationID coordinate:theCoordinate1];
[self.mapView addAnnotation:annotation];
}
}
This simply gets all map locations within the existing map view, and passes them off to the viewForAnnotation method. This all works fine.
The following is my MapAnnotations.h and MapAnnotations.m file code: -
.h
Code:
#import <Foundation/Foundation.h>
@protocol MyCLControllerDelegate
@required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
@end
@interface MapAnnotations : NSObject <CLLocationManagerDelegate, MKAnnotation> {
CLLocationManager *locationManager;
CLLocationCoordinate2D _coordinate;
id delegate;
NSString *_locationID;
NSString *_locationTitle;
NSString *_locationDate;
NSString *_locationType;
NSString *_locationNotes;
NSString *_locationPhoto;
NSNumber *_locationLat;
NSNumber *_locationLong;
NSString *_locationTime;
}
@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, strong) id delegate;
@property (copy) NSString *locationID;
@property (copy) NSString *locationTitle;
@property (copy) NSString *locationDate;
@property (copy) NSString *locationType;
@property (copy) NSString *locationNotes;
@property (copy) NSString *locationPhoto;
@property (copy) NSNumber *locationLat;
@property (copy) NSNumber *locationLong;
@property (copy) NSString *locationTime;
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation;
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error;
- (id)initWithName:(NSString*)locationTitle locationType:(NSString *)locationType locationID:(NSString *)locationID coordinate:(CLLocationCoordinate2D)coordinate;
@end
.m
Code:
#import "MapAnnotations.h"
@implementation MapAnnotations
@synthesize locationManager;
@synthesize delegate;
@synthesize locationID = _locationID;
@synthesize locationTitle = _locationTitle;
@synthesize locationDate = _locationDate;
@synthesize locationType = _locationType;
@synthesize locationNotes = _locationNotes;
@synthesize locationPhoto = _locationPhoto;
@synthesize locationLat = _locationLat;
@synthesize locationLong = _locationLong;
@synthesize locationTime = _locationTime;
@synthesize coordinate = _coordinate;
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self.delegate locationUpdate:newLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
- (id)init {
self = [super init];
if (self != nil) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
}
return self;
}
- (id)initWithName:(NSString*)locationTitle locationType:(NSString *)locationType locationID:(NSString *)locationID coordinate:(CLLocationCoordinate2D)coordinate {
if ((self = [super init])) {
_locationID = [locationID copy];
_locationTitle = [locationTitle copy];
_locationType = [locationType copy];
_coordinate = coordinate;
}
return self;
}
- (NSString *)title {
return _locationTitle;
}
- (NSString *)subtitle {
return _locationType;
}
@end
I would appreciate any pointers on how I can store the NSManagedObject of each annotation so I can pass it onto my MapDetailView. I need to do this so I can edit the attributes of the annotation.
If you require any further details let me know, and i'll post them if available.
Thanks very much in advance.