How to connect map annotation view buttons with da

2019-01-27 07:15发布

问题:

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{    
    //if it's user location, return nil
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    //try to dequeue an existing pin view first
    static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
    MKPinAnnotationView* pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
    pinView.animatesDrop = YES;
    pinView.canShowCallout = YES;
    pinView.pinColor = MKPinAnnotationColorRed;

    //button on the right for popup for pins
    UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [rightButton setTitle:annotation.title forState:UIControlStateNormal];
    [rightButton addTarget:self 
                    action:@selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
    pinView.rightCalloutAccessoryView = rightButton;

    //zoom button on the left of popup for pins
    UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
    [leftButton setTitle:annotation.title forState:UIControlStateNormal];
    [leftButton addTarget:self 
                    action:@selector(zoomToLocation:) forControlEvents:UIControlEventTouchUpInside];
    pinView.leftCalloutAccessoryView = leftButton;

    return pinView;
}

//for map view annotation right button
-(void)showDetails:(id)sender{
    NSLog(@"Annotation Click");
    //fypAppDelegate *appDelegate = (fypAppDelegate *)[[UIApplication sharedApplication] delegate];
    //Attraction *attraction = (Attraction *)[appDelegate.attractions objectAtIndex:sender];

    infoViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"info"];
    self.infoView = viewController;
    [self.navigationController pushViewController:infoView animated:true];
}

//for map view annotation left button
-(void)zoomToLocation:(id)sender{
    NSLog(@"Annotation Click");
}

Above is the delegate for the map annotations. I am able to show the pins and show the map annotation view but I don't know how to link the button events to the next view (infoViewController). So as you guys can see, the right button is the one I want to use to enable user to view more information about that place while the left button, I want to allow user to zoom in into the coordinates of that pin.

The data are from the database I've created. Below is how I did it just for reference (in case you guys might need it)

-(void)putPins
{
    fypAppDelegate *appDelegate = (fypAppDelegate *)[[UIApplication sharedApplication] delegate];   //get data
    [appDelegate readTopAttractions];   
    int i = 0;
    int count = appDelegate.attractions.count;
    self.mapAnnotations = [[NSMutableArray alloc] initWithCapacity:appDelegate.attractions.count];
    while (i < count) {
        Attraction *attraction = (Attraction *)[appDelegate.attractions objectAtIndex:i];
        i++;

        //Set coordinates for pin
        CLLocationCoordinate2D location;
        location.latitude = (double)[[attraction xCoor] doubleValue];
        location.longitude = (double)[[attraction yCoor] doubleValue];
        MapPin *mapPin = [[MapPin alloc] init];
        [mapPin setCoordinate:location];
        [mapPin setName: [attraction name]];
        NSString *desc = [attraction description];
        int i = 0, position;
        while(i < 50){
            if ([desc characterAtIndex:i] == ' '){
                position = i;
                i++;
            }
            else
                i++;
        }
        desc = [@"" stringByAppendingFormat:@"%@%@", [desc substringToIndex:position], @"..."];
        [mapPin setDescription: desc];
        [self.mapAnnotations addObject:mapPin];
    }

    [self.mapView addAnnotations:self.mapAnnotations];
}

please do tell me if you guys need more details. Thank you! =)

回答1:

In your showDetails: and zoomToLocation: methods, you can get a reference to the annotation whose callout button was tapped by doing the following:

MapPin *ann = (MapPin *)[mapView.selectedAnnotations objectAtIndex:0];


In zoomToLocation: you can then zoom in to that annotation using:

[mapView setRegion:
    MKCoordinateRegionMakeWithDistance(ann.coordinate, 500, 500) 
        //500 meters vertical span, 500 meters horizontal span
    animated:YES];

In showDetails:, you can pass ann or its properties to the detail view.


By the way, instead of calling custom methods using addTarget in viewForAnnotation, you can use the map view's calloutAccessoryControlTapped delegate method which gives more direct access to the annotation that was tapped. For example:

-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view 
    calloutAccessoryControlTapped:(UIControl *)control
{
    MapPin *ann = (MapPin *)view.annotation;

    if (control == view.rightCalloutAccessoryView)
    {
        NSLog(@"calloutAccessoryControlTapped: control=RIGHT");
        //show detail view (or you can call your custom method here)...
    }
    else
        if (control == view.leftCalloutAccessoryView)
        {
            NSLog(@"calloutAccessoryControlTapped: control=LEFT");
            //zoom in (or you can call your custom method here)...
        }
        else
        {
            NSLog(@"calloutAccessoryControlTapped: unknown control");
        }
}

Make sure you remove the addTarget calls from viewForAnnotation if you decide to use the calloutAccessoryControlTapped delegate method.



回答2:

You want to zoom in to the particular pin? Is that right?

Therefore you can use the setRegion:animated: - method from MKMapView.

Example:

mapView = MKMapView   
location = CLLLocationCoordinate2D  
METERS_PER_MILE = 1609.344 (defined as a Constant)

MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(location, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [mapView regionThatFits:region];

[mapView setRegion:adjustedRegion animated:YES];

AppleDocs
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html

http://developer.apple.com/library/IOs/#documentation/MapKit/Reference/MapKitDataTypesReference/Reference/reference.html