Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

objective c - How to connect map annotation view buttons with database to go to another view?

- (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! =)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...