I currently have a map view controller in which i add annotations to based on some parsed json data.
I'm trying to pass a value from this json data to the following segue and they way i want to do this is to add a custom variable to each annotation (venueId) so when it is pressed i can set a global value that the next segue gets via some logic.
However everything i have tried has resulted in a NUll value for the venueId, my code is as follows:
MyLocation.H
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface MyLocation : NSObject <MKAnnotation>{
NSNumber *venueId;
}
@property (nonatomic,readonly) NSNumber *venueId;
- (id)initWithName:(NSString *)name address:(NSString *)address coordinate:(CLLocationCoordinate2D)coordinate venueId:(NSNumber*)venueId;
@end
MyLocation.M
#import "MyLocation.h"
#import "GlobalData.h"
@interface MyLocation ()
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *address;
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
@end
@implementation MyLocation
@synthesize venueId = _venueId;
- (id) initWithName:(NSString *)name address:(NSString *)address coordinate:(CLLocationCoordinate2D)coordinate venueId:(NSNumber*)venueId{
if ((self = [super init])) {
self.name = name;
self.address = address;
self.coordinate = coordinate;
_venueId = self.venueId;
}
return self;
}
- (NSString *)title{
return _name;
}
- (NSString *)subtitle{
return _address;
}
- (CLLocationCoordinate2D)coordinate{
return _coordinate;
}
- (NSNumber *)venueId{
return _venueId;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{
NSLog(@"THE CALL OUT has been pressed");
}
@end
PLotting the venues in my MapViewController.M
// plot venues based on data passed in
- (void)plotVenuePositions{
for (id<MKAnnotation> annotation in _mapView.annotations){
// start fresh and remove any annotations in the view
[_mapView removeAnnotation:annotation];
}
for (NSDictionary *row in [[GlobalData sharedGlobalData]venuesArray]){
NSNumber *venueId = [row objectForKey:@"v_id"];
NSString *venueName =[row objectForKey:@"v_name"];
NSNumber *venueLat = [row objectForKey:@"v_lat"];
NSNumber *venueLon = [row objectForKey:@"v_lon"];
NSString *venueTown = [row objectForKey:@"t_name"];
// create co-ord
CLLocationCoordinate2D coordinate;
// set values
coordinate.latitude = venueLat.doubleValue;
coordinate.longitude = venueLon.doubleValue;
// create annotation instance
MyLocation *annotation = [[MyLocation alloc]initWithName:venueName address:venueTown coordinate:coordinate venueId:venueId];
// add annotation
[_mapView addAnnotation:annotation];
NSLog(@"VNEU ID IS %@",venueId);
NSLog(@"ANNOTATION name is %@", annotation.title);
NSLog(@"ANNOTATION subtitle is %@", annotation.subtitle);
NSLog(@"ANNOTATION description is %@", annotation.description);
NSLog(@"ANNOTATION venue ID IS %@", (MyLocation *)annotation.venueId);
}
}
And finally the annotation checks in MapViewController.M
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString *identifier = @"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]]) {
MKAnnotationView *annotationView = (MKAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.image = [UIImage imageNamed:@"pin_orange.png"];
// set the cell to have a callout button
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else{
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
In the initWithName
method, this line:
_venueId = self.venueId;
does not set the current location's venue id to the init method's parameter value venueId
.
It sets it to the current location's property value for venueId
.
Since that property value is backed by _venueId
, the line is effectively setting it equal to itself and since it is initially null, it stays null.
The line should be:
_venueId = venueId;
or if you are not using ARC:
_venueId = [venueId retain];
This line will, however, give you a compiler warning that the "local variable hides the instance variable". This is because the method parameter name is the same as the property name.
Although the change will work, to remove the compiler warning, change the name of the method parameter to something other than venueId
(eg. iVenueId
) and then the changed line would be:
_venueId = iVenueId;