5

I want to add a disclosure button to a MKAnnotation to segue to another view.

The button should look like this one:

Image

Here's my .h and .m files.


.h file

//
//  POI.h
//

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

@interface POI : NSObject <MKAnnotation> {

    NSString *title;
    NSString *subtitle;
    CLLocationCoordinate2D coordinate;
}

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

- (id)initWithCoordinate:(CLLocationCoordinate2D)_coordinate title:(NSString *)_titolo andSubTitle:(NSString *)_sottotitolo;


@end

.m file

//
//  POI.m

#import "POI.h"



@implementation POI

@synthesize title, subtitle, coordinate;
-(id)initWithCoordinate:(CLLocationCoordinate2D)_coordinate title:(NSString *)_titolo andSubTitle:(NSString *)_sottotitolo {

    [self setTitle:_titolo];
    [self setSubtitle:_sottotitolo];
    [self setCoordinate:_coordinate];



    return self;
}

@end

in my ViewController i call this using:

  pinLocation.latitude = 4.8874;
    pinLocation.longitude = 1.400;
    POI *poi = [[POI alloc] initWithCoordinate:pinLocation title:@"foo" andSubTitle:@"bar"];
    [_mapView addAnnotation:poi];
IluTov
  • 6,807
  • 6
  • 41
  • 103
fntlnz
  • 411
  • 2
  • 6
  • 14

2 Answers2

12

Three steps.

1) In your header file (.h) or your implementation file's (.m) class extension conform to MKMapViewDelegate:

@interface ViewController : UIViewController <MKMapViewDelegate> { ... } 

2) Set your view controller as the delegate of MKMapViewDelegate to receive delegate callbacks. Commonly done in viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.mapView.delegate = self;
}

3) Implement the following delegate function to show the disclosure button:

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{   
    MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc]     initWithAnnotation:annotation reuseIdentifier:@"pinLocation"];

    newAnnotation.canShowCallout = YES;
    newAnnotation.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    return newAnnotation;
}

the following function will assist in determining what action (in your case, presenting a view) is taken upon touching the disclosure button.

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    //launch a new view upon touching the disclosure indicator
    TestVCViewController *tvc = [[TestVCViewController alloc] initWithNibName:@"TestVCViewController" bundle:nil];
    [self presentViewController:tvc animated:YES completion:nil];
}
Pouria Almassi
  • 1,580
  • 2
  • 17
  • 26
  • Thank you for your reply, i tried to add your code but it doesn't show nothing... – fntlnz Dec 26 '12 at 23:06
  • Do you currently have any points plotted? Have you declared the use of in the header file of your viewcontroller? You'll need to do this to access the MapKit delegate methods. I'll clarify this in my answer. – Pouria Almassi Dec 26 '12 at 23:35
  • Yes, this is my header, thank you! [code] @interface LFViewController : UIViewController { BOOL _doneInitialZoom; CLLocationManager *locationManager; }[code] – fntlnz Dec 26 '12 at 23:47
  • Ok, i solved implementing your code and adding a _mapView.delegate = self; in - (void)viewDidLoad , Thank you so much! – fntlnz Dec 27 '12 at 00:07
  • 1
    If you are showing `userLocation`, make sure to return an `MKPinAnnotationView` with a different identifier in `if (annotation == mapView.userLocation) {` – Patrick Mar 13 '15 at 12:47
  • Hey! Your answer helped me. But can you please tell me, If I have 15 pins currently showing then how can I detect which pin has been tapped on calloutAccessoryControlTapped: – iGatiTech Feb 25 '16 at 11:31
  • @Gati if your view controller conforms to the `MKMapViewDelegate` protocol and you implement the delegate method `-mapView:annotationView:calloutAccessoryControlTapped:` (implemented above) then you should receive the callback when that control is tapped. – Pouria Almassi Feb 28 '16 at 23:55
  • Yeah! That's true. I am receiving callback event when control is tapped. But I am asking how to identify which pin has been tapped? Means suppose there are 15 pins and if I pressed 5th one. Then how can I detect that I have pressed no.5 pin in -mapView:annotationView:calloutAccessoryControlTapped: method. – iGatiTech Feb 29 '16 at 04:35
  • using above methods , i am getting multiple pins on same location and i am, having only one . then why it is showing two pins ? any idea ? and i can not see title and sub title touching on those pins . before using these methods it was showing title perfectly but now it is not . anyone knows why it is happening like this ? – Moxarth Jun 27 '17 at 04:56
0

In your - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation method use this:

annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

where annotationView is the view to be returned.

sqreept
  • 5,236
  • 3
  • 21
  • 26