Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

akesson

macrumors newbie
Original poster
Oct 22, 2010
7
0
Hi guys,

I have a mapview with a few pins on it. The pins are loading its data from a plist-file (title, longitude and latitude). I've also added a detailview where you get more info about the pin that gets tapped.
The pins are showing just fine on the map and I can tap on them to get to the detailview so my question is how do I send the, for example, the title from the mapview to my detailview when the disclosebutton is tapped?

I know it's something like this detailViewController.title = annotation.title, but I don't know how to fetch the annotation data.

Hope that somebody can get me on the right track :)

Here's my code:

RootViewController.h
Code:
@interface RootViewController : UIViewController <MKMapViewDelegate> {
	IBOutlet MKMapView *map;
	
	NSArray *cam;
}

@end

RootViewController.m
Code:
- (void)viewDidLoad {
    [super viewDidLoad];
	
        map.delegate = self;
	
	cam = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] 
														 pathForResource:@"Cam" 
														 ofType:@"plist"]];
	
	double minLat = [[cam valueForKeyPath:@"@min.latitude"] doubleValue];
	double maxLat = [[cam valueForKeyPath:@"@max.latitude"] doubleValue];
	double minLon = [[cam valueForKeyPath:@"@min.longitude"] doubleValue];
	double maxLon = [[cam valueForKeyPath:@"@max.longitude"] doubleValue];
	
	MKCoordinateRegion region;
	region.center.latitude = (maxLat + minLat) / 2.0;
	region.center.longitude = (maxLon + minLon) / 2.0;
	region.span.latitudeDelta = (maxLat - minLat) * 1.05;
	region.span.longitudeDelta = (maxLon - minLon) * 1.05;
	map.region = region;
	
	for (NSDictionary *camDict in cam){
		MyAnnotation *annotation = [[MyAnnotation alloc] initWithDictionary:camDict];
		[map addAnnotation:annotation];
		[annotation release];
	}
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
	MKPinAnnotationView *annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
    [annView setAnimatesDrop:YES];
    [annView setCanShowCallout:YES];
    [annView setSelected:YES];
    [annView setUserInteractionEnabled: YES];
    
    UIButton *discloseButton = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
    [discloseButton addTarget: self action: @selector(showMyView:) forControlEvents: UIControlEventTouchUpInside];
    annView.rightCalloutAccessoryView = discloseButton;
    
    return annView;
}

// Push to detailView with some data
- (IBAction)showMyView:(id)sender {
		
	DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
	
        // something like this.
	//detailViewController.title = annotation.title;
	//detailViewController.tempAdress = annotation.subtitle;
	
	[self.navigationController pushViewController:detailViewController animated:YES];
	[detailViewController release];
												  
}

MyAnnotation.h
Code:
@interface MyAnnotation : NSObject <MKAnnotation> {
	CLLocationCoordinate2D coordinate;
	NSString *title;
	NSString *subtitle;
}

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

MyAnnotation.m
Code:
- (id) initWithDictionary:(NSDictionary *) dict
{
	self = [super init];
	if (self != nil) {
		coordinate.latitude = [[dict objectForKey:@"latitude"] doubleValue];
		coordinate.longitude = [[dict objectForKey:@"longitude"] doubleValue];
		self.title = [dict objectForKey:@"name"];
		self.subtitle = [dict objectForKey:@"address"];
	}
	return self;
}
 
I normally do this:
Code:
pin.rightCalloutAccessoryView =
    [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

And:
Code:
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control {
    NSLog(@"%@", pin.annotation.title);
    ...
}

Hope this clarifies things :)
 
Hope this clarifies things :)

Thanks for a quick answer :)

Hm, I get that I can fetch the title(s) in the viewForAnnotation-method. Seems very logical.
Code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
	
    MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
    [pin setAnimatesDrop:YES];
    [pin setCanShowCallout:YES];
    [pin setSelected:YES];
    [pin setUserInteractionEnabled: YES];
    
    UIButton *discloseButton = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
    [discloseButton addTarget: self action: @selector(showMyView:) forControlEvents: UIControlEventTouchUpInside];
    pin.rightCalloutAccessoryView = discloseButton;

    NSLog(@"%@", pin.annotation.title);
	
    return pin;
}

However I can't figure out how to fetch it in my action-method. Feels like I banged my head agains the wall all day...
Code:
- (IBAction)showMyView:(id)sender {
    DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
	
    // Something like this --
    //detailViewController.title = pin.annotation.title;
	
    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];
												  
}
 
Did you notice method mapView:annotationView:calloutAccessoryControlTapped: in my original reply?
 
Did you notice method mapView:annotationView:calloutAccessoryControlTapped: in my original reply?

Doh! Didn't notice that, I was probably to tired :rolleyes:

Thank you very much ianray, it's working! :) :)


Here's the code btw

Code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
	
    MKPinAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
    [pin setAnimatesDrop:YES];
    [pin setCanShowCallout:YES];
    [pin setSelected:YES];
    [pin setUserInteractionEnabled: YES];
    
    pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
	
    return pin;
}

Code:
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control {	
	DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
	
	detailViewController.title = pin.annotation.title;	
	
	[self.navigationController pushViewController:detailViewController animated:YES];
	[detailViewController release];
}
 
Hmm, still have one problem I can't figure out.

If I want to add more than the title and the subtitle, a url for example (to be shown in the detailview).

Shouldn't I be able just do like this to add a url:

I'm getting an error saying: error: accessing unknown 'detailUrl' getter method

MyAnnotation.h
Code:
@interface MyAnnotation : NSObject <MKAnnotation> {
	CLLocationCoordinate2D coordinate;
	NSString *title;
	NSString *subtitle;
	NSString *detailUrl;
}

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

MyAnnotation.m
Code:
- (id) initWithDictionary:(NSDictionary *) dict
{
	self = [super init];
	if (self != nil) {
		coordinate.latitude = [[dict objectForKey:@"latitude"] doubleValue];
		coordinate.longitude = [[dict objectForKey:@"longitude"] doubleValue];
		self.title = [dict objectForKey:@"name"];
		self.subtitle = [dict objectForKey:@"adress"];
		self.detailUrl = [dict objectForKey:@"url"];
	}
	return self;
}

and in my RootViewController.m
Code:
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control {	
	DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
	
	detailViewController.title = pin.annotation.title;	
	detailViewController.theUrl = pin.annotation.detailUrl;
	
	[self.navigationController pushViewController:detailViewController animated:YES];
	[detailViewController release];
}

Thanks!
 
The pin.annotation has type
Code:
id <MKAnnotation>

You will need to cast to your data type (MyAnnotation).
 
The pin.annotation has type
Code:
id <MKAnnotation>

You will need to cast to your data type (MyAnnotation).

I'm not by my computer atm, but I'm not really sure what you mean. Can you explain abit more? Sorry if I'm being stupid :eek:
 
I'm not by my computer atm, but I'm not really sure what you mean. Can you explain abit more? Sorry if I'm being stupid :eek:

The type of pin.annotation is 'id <MKAnnotation>' -- you can check this from the documentation at: http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKAnnotation_Protocol/Reference/Reference.html%23//apple_ref/occ/intf/MKAnnotation.

Now the object itself was allocated by you (and passed to MKMapView method addAnnotation).

So we know that we can safely type-cast from 'id <MKAnnotation>' to MyAnnotation.

Is that clearer? :)
 
The type of pin.annotation is 'id <MKAnnotation>' -- you can check this from the documentation at: http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKAnnotation_Protocol/Reference/Reference.html%23//apple_ref/occ/intf/MKAnnotation.

Now the object itself was allocated by you (and passed to MKMapView method addAnnotation).

So we know that we can safely type-cast from 'id <MKAnnotation>' to MyAnnotation.

Is that clearer? :)

YES! Thank you very very vey much :):):)

(Don't know if this is what you meant, but it's working :D)

Code:
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control {	
	DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
	
	MyAnnotation *theAnnotation = (MyAnnotation *) pin.annotation;
	
	detailViewController.title = theAnnotation.title;
	detailViewController.url = theAnnotation.theUrl;
	
	[self.navigationController pushViewController:detailViewController animated:YES];
	[detailViewController release];
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.