Domanda

I have a problem with my MKPointAnnotation points dropped on a map. I'll explain.

Scenario:

Read JSON from server -> Drop pins on the map -> When a pin is clicked, then open a new view with a parameter passed to the view. The parameter must be binded to the pin.

My code so far:

JSON(so example purposes only)

{"places":[{"lat":"30.03","lng":"40.31","id":"1"}]}

Read JSON and add points to map:

NSString *markersJSON=@"http://test.com/json.php";
NSURLRequest *requestUsername = [NSURLRequest requestWithURL:[NSURL URLWithString:markersJSON]];
NSData *response = [NSURLConnection sendSynchronousRequest:requestUsername
                                             returningResponse:nil error:nil];
NSError *jsonParsingError = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:response
                                                         options:0 error:&jsonParsingError];
markerArray = [json objectForKey:@"places"];

    for (NSDictionary *jsonObj in markerArray ){
        latJSON=[jsonObj objectForKey:@"lat"];
        lngJSON=[jsonObj objectForKey:@"lng"];
        alertID=[jsonObj objectForKey:@"id"];
        CLLocationCoordinate2D myCoordinate = {[latJSON doubleValue], [lngJSON doubleValue]};
        MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
        point.coordinate = myCoordinate;
        point.title=[jsonObj objectForKey:@"title"];
        point.subtitle=[jsonObj objectForKey:@"description"];        
        [self.mapView addAnnotation:point];
    }

When annotation is clicked, open new view with a variable "id" from JSON corresponding to the pin.

- (void)mapView:(MKMapView *)map annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
{   
ViewController *yourViewController = (ViewController *)[navStoryBoard instantiateViewControllerWithIdentifier:@"details_alert"];

**//STUCKED HERE**

[self.navigationController pushViewController:yourViewController animated:YES];

}

The thing is that i can't find a way to bind the id from JSON to the corresponding pin so every time a user touches a pin, i would know that pin with id=1 is touched and then do other operations.For example, open a detailed view with data fetched from DB.

I hope you will understand what i am trying to do.

Thank you!

EDIT: Almost there.

//Annotation.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface Annotation : NSObject<MKAnnotation> {
    CLLocationCoordinate2D coordinate;
    NSString *title;
    NSString *subtitle;
    NSString *placeId;
}

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic,readonly,copy) NSString *title;
@property (nonatomic,readonly,copy) NSString *subtitle;
@property (nonatomic) NSString *placeId;

- (id)initWithCoordinates:(CLLocationCoordinate2D)location placeName:(NSString *)placeName description:(NSString *)description placeId:(NSString *)placeId;

@end

//Annotation.m

#import "Annotation.h"

@implementation Annotation

@synthesize coordinate;
@synthesize title;
@synthesize subtitle;
@synthesize placeId;

- (id)initWithCoordinates:(CLLocationCoordinate2D)location placeName:placeName description:description placeId:(NSString *)placeIda;
{
    self = [super init];
    if (self != nil) {
        coordinate = location;
        title = placeName;
        subtitle = description;
        placeId=placeIda;

    }
    return self;
}

- (void)dealloc {

}
@end


Add pins from JSON loop:

for (NSDictionary *jsonObj in markerArray ){
        latJSON=[jsonObj objectForKey:@"lat"];
        lngJSON=[jsonObj objectForKey:@"lng"];
        alertID=[jsonObj objectForKey:@"id"];
        CLLocationCoordinate2D myCoordinate = {[latJSON doubleValue], [lngJSON doubleValue]};

       Annotation *pin = [[Annotation alloc] initWithCoordinates:myCoordinate placeName:[jsonObj objectForKey:@"title"] description:[jsonObj objectForKey:@"description"] placeId:alertID];
       [self.mapView addAnnotation:pin];
    }

Touch pin and pass pin ID to other view

- (void)mapView:(MKMapView *)map annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
{
    id <MKAnnotation> annotation = [view annotation];
    CLLocationCoordinate2D centerCoordinate =[annotation coordinate ];

    ViewController *yourViewController = (ViewController *)[navStoryBoard instantiateViewControllerWithIdentifier:@"details_alert"];

    //////
    Annotation *mysc=view.annotation;
    [yourViewController setValue:[NSString stringWithFormat:@"%lu",(unsigned long)mysc.placeId] forKey:@"sendAlertID"];
    //////

    [self.navigationController pushViewController:yourViewController animated:YES];

}

All the above work.But the mysc.placeId passed to the viewController is totaly wrong. For example,for the pin with the id=1(from JSON), the NSLog of sendAlertID (variable from yourViewController is 245513072 !!!

È stato utile?

Soluzione

- (void)mapView:(MKMapView *)map annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
{   
ViewController *yourViewController = (ViewController *)[navStoryBoard instantiateViewControllerWithIdentifier:@"details_alert"];

**//STUCKED HERE**

[self.navigationController pushViewController:yourViewController animated:YES];

}

So:

Just create your own object that complies with the MKAnnotation protocol. You can then:

MyAnnotationObject *object = (MyAnnotationObject *)view.annotation;
NSString *jsonId = object.id;

Instead of:

 MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
 point.coordinate = myCoordinate;
 point.title=[jsonObj objectForKey:@"title"];
 point.subtitle=[jsonObj objectForKey:@"description"];   

You would use your own Class:

MyAnnotationObject *annotation = [[MyAnnotationObject alloc] initWithCoordinates:coordinates title:title subtitle:subtitle];

You can see this simple example on how to do it.


You just need two things:

  1. Comply with MKAnnotation Protocol: @interface MyAnnotationObject :NSObject <MKAnnotation>
  2. Create @property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

Altri suggerimenti

Every MKMapAnnotationView that is drawed in a MKMapView should have a property called annotation which implements MKAnnotation protocol.

If you implement a custom annotation, you can add as many parameters as you want to it.

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface STMapAnnotation : NSObject <MKAnnotation>
@property (nonatomic,readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic,readonly,copy) NSString *title;
@property (nonatomic,readonly,copy) NSString *subtitle;
@property (nonatomic) NSUInteger placeId;

- (id)initWithTitle:(NSString *)title
           subtitle:(NSString *)subtitle
        coordinates:(CLLocationCoordinate2D)coordinates
            placeId:(NSUInteger)placeId;
@end

You'll then crate and add this custom annotation to the MKMapView so in the delegate method you can retrieve any custom information you added.

- (void)mapView:(MKMapView *)map annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
{   
         ViewController *yourViewController = (ViewController *)[navStoryBoard instantiateViewControllerWithIdentifier:@"details_alert"];
         STMapAnnotation *myCustomAnnotation = view.annotation;
         yourViewController.placeId = myCustomAnnotation.placeId;
         [self.navigationController pushViewController:yourViewController animated:YES];

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top