I cannot see the second entry in the Map
and take me to DetailViewController2
.
Is there any way to fix this?
#import "MapViewController.h"
#import "DetailViewController.h"
#import "DetailViewController2.h"
#import "SFAnnotation.h" // annotation for the city of San Francisco
#import "BridgeAnnotation.h" // annotation for the Golden Gate bridge
#import "CustomAnnotation.h" // annotation for the Tea Garden
@interface MapViewController () <MKMapViewDelegate>
@property (nonatomic, weak) IBOutlet MKMapView *mapView;
@property (nonatomic, strong) NSMutableArray *mapAnnotations;
@property (nonatomic, strong) UIPopoverController *bridgePopoverController;
@property (nonatomic, strong) UIPopoverController *sfPopoverController;
@property (nonatomic, strong) UIPopoverController *customPopoverController;
@end
#pragma mark -
@implementation MapViewController
- (void)gotoDefaultLocation
{
// EMPEZAR CON UNA LOCALIZACIÓN DETERMINADA
MKCoordinateRegion newRegion;
newRegion.center.latitude = 41.651981;
newRegion.center.longitude = -4.728561;
newRegion.span.latitudeDelta = 0.1;
newRegion.span.longitudeDelta = 0.1;
self.mapView.showsUserLocation = YES;
[self.mapView setRegion:newRegion animated:YES];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// restore the nav bar to translucent
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// create a custom navigation bar button and set it to always says "Back"
UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init];
temporaryBarButtonItem.title = @"Back";
self.navigationItem.backBarButtonItem = temporaryBarButtonItem;
// create out annotations array (in this example only 3)
self.mapAnnotations = [[NSMutableArray alloc] initWithCapacity:2];
// annotation for the City of San Francisco
SFAnnotation *sfAnnotation = [[SFAnnotation alloc] init];
[self.mapAnnotations addObject:sfAnnotation];
// annotation for Golden Gate Bridge
BridgeAnnotation *bridgeAnnotation = [[BridgeAnnotation alloc] init];
[self.mapAnnotations addObject:bridgeAnnotation];
// annotation for Tea Garden
CustomAnnotation *customAnnotation = [[CustomAnnotation alloc] init];
[self.mapAnnotations addObject:customAnnotation];
[self allAction:self]; // initially show all annotations
}
#pragma mark - Button Actions
- (void)gotoByAnnotationClass:(Class)annotationClass
{
// user tapped "City" button in the bottom toolbar
for (id annotation in self.mapAnnotations)
{
if ([annotation isKindOfClass:annotationClass])
{
// remove any annotations that exist
[self.mapView removeAnnotations:self.mapView.annotations];
// add just the city annotation
[self.mapView addAnnotation:annotation];
[self gotoDefaultLocation];
}
}
}
- (IBAction)cityAction:(id)sender
{
[self gotoByAnnotationClass:[SFAnnotation class]];
}
- (IBAction)bridgeAction:(id)sender
{
// user tapped "Bridge" button in the bottom toolbar
[self gotoByAnnotationClass:[BridgeAnnotation class]];
}
- (IBAction)teaGardenAction:(id)sender
{
// user tapped "Tea Garden" button in the bottom toolbar
[self gotoByAnnotationClass:[CustomAnnotation class]];
}
- (IBAction)allAction:(id)sender
{
// user tapped "All" button in the bottom toolbar
// remove any annotations that exist
[self.mapView removeAnnotations:self.mapView.annotations];
// add all 3 annotations
[self.mapView addAnnotations:self.mapAnnotations];
[self gotoDefaultLocation];
}
#pragma mark - MKMapViewDelegate
// user tapped the disclosure button in the bridge callout
//
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
// here we illustrate how to detect which annotation type was clicked on for its callout
id <MKAnnotation> annotation1 = [view annotation];
if ([annotation1 isKindOfClass:[BridgeAnnotation class]])
{
NSLog(@"clicked Golden Gate Bridge annotation");
DetailViewController *detailViewController = [[self storyboard] instantiateViewControllerWithIdentifier:@"DetailViewController"];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
// for iPad, we use a popover
if (self.bridgePopoverController == nil)
{
_bridgePopoverController = [[UIPopoverController alloc] initWithContentViewController:detailViewController];
}
[self.bridgePopoverController presentPopoverFromRect:control.bounds
inView:control
permittedArrowDirections:UIPopoverArrowDirectionLeft
animated:YES];
}
else
{
// for iPhone we navigate to a detail view controller using UINavigationController
[self.navigationController pushViewController:detailViewController animated:YES];
}
}
}
// user tapped the disclosure button in city of San Francisco callout
//
- (void)mapView:(MKMapView *)mapView annotationView2:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
// here we illustrate how to detect which annotation type was clicked on for its callout
id <MKAnnotation> annotation2 = [view annotation];
if ([annotation2 isKindOfClass:[SFAnnotation class]])
{
NSLog(@"clicked City of San Francisco annotation");
DetailViewController *detailViewController2 = [[self storyboard] instantiateViewControllerWithIdentifier:@"DetailViewController2"];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
// for iPad, we use a popover
if (self.sfPopoverController == nil)
{
_sfPopoverController = [[UIPopoverController alloc] initWithContentViewController:detailViewController2];
}
[self.sfPopoverController presentPopoverFromRect:control.bounds
inView:control
permittedArrowDirections:UIPopoverArrowDirectionLeft
animated:YES];
}
else
{
// for iPhone we navigate to a detail view controller using UINavigationController
[self.navigationController pushViewController:detailViewController2 animated:YES];
}
}
}
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *returnedAnnotationView = nil;
// in case it's the user location, we already have an annotation, so just return nil
if (![annotation isKindOfClass:[MKUserLocation class]])
{
// handle our three custom annotations
//
if ([annotation isKindOfClass:[BridgeAnnotation class]]) // for Golden Gate Bridge
{
returnedAnnotationView = [BridgeAnnotation createViewAnnotationForMapView:self.mapView annotation:annotation];
// add a detail disclosure button to the callout which will open a new view controller page or a popover
//
// note: when the detail disclosure button is tapped, we respond to it via:
// calloutAccessoryControlTapped delegate method
//
// by using "calloutAccessoryControlTapped", it's a convenient way to find out which annotation was tapped
//
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:nil action:nil forControlEvents:UIControlEventTouchUpInside];
((MKPinAnnotationView *)returnedAnnotationView).rightCalloutAccessoryView = rightButton;
}
else if ([annotation isKindOfClass:[SFAnnotation class]]) // for City of San Francisco
{
returnedAnnotationView = [SFAnnotation createViewAnnotationForMapView:self.mapView annotation:annotation];
// add a detail disclosure button to the callout which will open a new view controller page or a popover
//
// note: when the detail disclosure button is tapped, we respond to it via:
// calloutAccessoryControlTapped delegate method
//
// by using "calloutAccessoryControlTapped", it's a convenient way to find out which annotation was tapped
//
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:nil action:nil forControlEvents:UIControlEventTouchUpInside];
((MKPinAnnotationView *)returnedAnnotationView).rightCalloutAccessoryView = rightButton;
}
else if ([annotation isKindOfClass:[CustomAnnotation class]]) // for City of Tea Garden
{
returnedAnnotationView = [CustomAnnotation createViewAnnotationForMapView:self.mapView annotation:annotation];
// add a detail disclosure button to the callout which will open a new view controller page or a popover
//
// note: when the detail disclosure button is tapped, we respond to it via:
// calloutAccessoryControlTapped delegate method
//
// by using "calloutAccessoryControlTapped", it's a convenient way to find out which annotation was tapped
//
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:nil action:nil forControlEvents:UIControlEventTouchUpInside];
((MKPinAnnotationView *)returnedAnnotationView).rightCalloutAccessoryView = rightButton;
}
}
return returnedAnnotationView;
}
@end
This method:
- (void)mapView:(MKMapView *)mapView annotationView2:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
will not be called by the map view because it's not named exactly mapView:annotationView:calloutAccessoryControlTapped:
.
Naming the method annotationView2
does not automatically associate it with your "second" annotation. Delegate methods must be named exactly as defined by the protocol (MKMapViewDelegate
in this case).
You must handle all callout button taps in this one method:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
In there, you can check the annotation's class and handle accordingly (like you are already doing with BridgeAnnotation
). For example:
if ([annotation1 isKindOfClass:[BridgeAnnotation class]])
{
//code for Bridge annotation...
}
else
if ([annotation1 isKindOfClass:[SFAnnotation class]])
{
//code for SF annotation...
}
else ...