2012-03-13 3 views
1

내 응용 프로그램에는 여러 사용자 정의 핀이있는 mapView가 있습니다.여러 핀을 사용하여 경로 계산

나는 이것을하려고한다 : showCallout에서 AlertView가 나타나고 경로를 계산할 것인지를 알려준다. 이 기능은 한 위치에서만 작동합니다. 아니면 하나의 메소드 만 호출되므로 대상이 하나만 있습니다.

여기 (I 9 개 목적지를 가지고,하지만 난 단지 2 코드 짧은를 만들기 위해 게시) 내 코드입니다 :

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

[mapView setMapType:MKMapTypeStandard]; 
[mapView setZoomEnabled:YES]; 
[mapView setScrollEnabled:YES]; 
[mapView setDelegate:(id)self]; 

MKCoordinateRegion TavernaCongiura = { {0.0, 0.0} , {0.0, 0.0} }; 
TavernaCongiura.center.latitude = 40.380784; 
TavernaCongiura.center.longitude = 15.541373; 
TavernaCongiura.span.longitudeDelta = 0.004f; 
TavernaCongiura.span.latitudeDelta = 0.004f; 
[mapView setRegion:TavernaCongiura animated:YES]; 
mapView.showsUserLocation = YES; 

TeggianoAnnotation *ann0 = [[TeggianoAnnotation alloc] init]; 
ann0.title = @"Taverna de la Congiura"; 
ann0.subtitle = @"Antipasto"; 
ann0.coordinate = TavernaCongiura.center; 
[mapView addAnnotation: ann0]; 

MKCoordinateRegion TavernaDeiMori = { {0.0, 0.0} , {0.0, 0.0} }; 
TavernaDeiMori.center.latitude = 40.380535; 
TavernaDeiMori.center.longitude = 15.542028; 
TavernaDeiMori.span.longitudeDelta = 0.004f; 
TavernaDeiMori.span.latitudeDelta = 0.004f; 
[mapView setRegion:TavernaDeiMori animated:YES]; 

TeggianoAnnotation *ann1 = [[TeggianoAnnotation alloc] init]; 
ann1.title = @"Taverna dei Mori"; 
ann1.subtitle = @"Parmatieddi"; 
ann1.coordinate = TavernaDeiMori.center; 
[mapView addAnnotation: ann1]; 

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation  
*)newLocation fromLocation:(CLLocation *)oldLocation { 
if (newLocation.horizontalAccuracy == oldLocation.horizontalAccuracy) { 
    [self->locationManager stopUpdatingLocation]; 
    CLLocationCoordinate2D coords = newLocation.coordinate; 
    NSString *stringURL = [NSString stringWithFormat:@"http://maps.google.com 
/maps?saddr=%g,%g&daddr=40.380784,15.541373", coords.latitude, coords.longitude]; 
    NSURL *url = [NSURL URLWithString:stringURL]; 
    [[UIApplication sharedApplication] openURL:url]; 
} 
} 

- (void)locationManagerMori:(CLLocationManager *)manager didUpdateToLocation: 
(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
if (newLocation.horizontalAccuracy == oldLocation.horizontalAccuracy) { 
    [self->locationManager stopUpdatingLocation]; 
    CLLocationCoordinate2D coords = newLocation.coordinate; 
    NSString *stringURL = [NSString stringWithFormat:@"http://maps.google.com 
/maps?saddr=%g,%g&daddr=40.380535,15.542028", coords.latitude, coords.longitude]; 
    NSURL *url = [NSURL URLWithString:stringURL]; 
    [[UIApplication sharedApplication] openURL:url]; 
} 
} 

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

UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
if ([[annotation title] isEqualToString:@"Taverna de la Congiura"]) { 
    [advertButton addTarget:self action:@selector(buttonCongiura:) 
forControlEvents:UIControlEventTouchUpInside]; 
    MyPin.image = [UIImage imageNamed:@"CongiuraMappa.png"];  
} 
if ([[annotation title] isEqualToString:@"Taverna dei Mori"]) { 
    [advertButton addTarget:self action:@selector(buttonMori:) 
forControlEvents:UIControlEventTouchUpInside]; 
    MyPin.image = [UIImage imageNamed:@"MoriMappa.png"];  
} 
MyPin.rightCalloutAccessoryView = advertButton; 
MyPin.draggable = NO; 
MyPin.highlighted = YES; 
MyPin.canShowCallout = YES; 
return MyPin; 
} 

-(void)buttonCongiura:(id)sender { 
UIAlertView *alertViewCongiura; 
alertViewCongiura = [[UIAlertView alloc] initWithTitle:@"Taverna de la Congiura" 
message:@"Calcola Percorso" delegate:self cancelButtonTitle:@"Annulla" 
otherButtonTitles:@"Calcola", nil]; 
[alertViewCongiura show]; 
} 

-(void)buttonMori:(id)sender { 
UIAlertView *alertViewMori; 
alertViewMori = [[UIAlertView alloc] initWithTitle:@"Taverna dei Mori" 
message:@"Calcola Percorso" delegate:self cancelButtonTitle:@"Annulla" 
otherButtonTitles:@"Calcola", nil]; 
[alertViewMori show]; 
} 

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
if (buttonIndex == 1) { 
    self->locationManager = [[CLLocationManager alloc] init]; 
    self->locationManager.delegate = (id)self; 
    [self->locationManager startUpdatingLocation]; 
} 

if (buttonIndex == 2) { 
    self->locationManagerMori = [[CLLocationManager alloc] init]; 
    self->locationManagerMori.delegate = (id)self; 
    [self->locationManagerMori startUpdatingLocation]; 
} 
} 

문제는 첫 번째

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation  
*)newLocation fromLocation:(CLLocation *)oldLocation 

가 호출 될 것입니다.

답변

1

사용중인 각 위치 관리자 인스턴스에 대해 대리자 메서드에 대해 다른 이름을 사용할 수 없습니다. 각 위치 관리자는 여전히 CLLocationManagerDelegate 프로토콜에 정의 된 메소드를 호출합니다.

당신에게 manager 매개 변수는 작성중인 경우 (예. if (manager == locationManagerMori)) 중 하나와 동일한 경우 관리자가 확인하여 호출 확인하시기 바랍니다.

하지만 먼저 각 주석에 대해 별도의 위치 관리자 인스턴스를 만들 필요는 없습니다. 대신


는 하나 개의 위치 관리자 인스턴스를 유지하고 위임 방법, 당신은 현재 선택된 주석이 무엇인지 알 수 있고, URL 문자열에서의 좌표를 사용합니다. 예 :

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
    fromLocation:(CLLocation *)oldLocation 
{ 
    if (newLocation.horizontalAccuracy == oldLocation.horizontalAccuracy) 
     //the above if-condition looks a little suspicious by the way 
    { 
     if (mapView.selectedAnnotations.count == 0) 
     { 
      //no annotation selected, do nothing 
      return; 
     } 

     //there can only be one selected annotation so get the one at index 0 
     id<MKAnnotation> selectedAnnotation = 
      [mapView.selectedAnnotations objectAtIndex:0]; 


     [self->locationManager stopUpdatingLocation]; 
     CLLocationCoordinate2D coords = newLocation.coordinate; 

     NSString *stringURL = [NSString stringWithFormat: 
      @"http://maps.google.com/maps?saddr=%g,%g&daddr=%g,%g", 
      coords.latitude, coords.longitude, 
      selectedAnnotation.coordinate.latitude, 
      selectedAnnotation.coordinate.longitude]; 

     NSURL *url = [NSURL URLWithString:stringURL]; 

     //stop updating location to avoid possible endless loop 
     //when user comes back to this app... 
     [manager stopUpdatingLocation]; 

     [[UIApplication sharedApplication] openURL:url]; 
    } 
} 

각 주석에 대해 별도의 버튼 동작 방법이 필요하지 않습니다. 하나의 버튼 동작 메서드를 만들고 동일한 기술을 사용하여 선택한 주석을 가져올 수 있습니다.

또 다른 문제점은 경고보기 clickedButtonAtIndex 방법입니다. 경고보기의 단추 색인을보고 어떤 주석인지 확인하는 것 같습니다. 해당 색인은 Annulla 또는 Calcola 버튼이됩니다 (주석이 아님).

각 주석에 대해 별도의 위치 관리자를 만들 필요가 없으므로 경고보기가 어떤 주석인지 알 필요가 없습니다. 사용자가 Annulla 또는 Calcola를 탭했는지 확인해야합니다.

if (buttonIndex == alertView.firstOtherButtonIndex) 
{ 
    self->locationManager = [[CLLocationManager alloc] init]; 
    self->locationManager.delegate = (id)self; 
    self->locationManager startUpdatingLocation]; 
} 
+0

감사합니다. 감사합니다. 그것은 거의 완벽하게 작동합니다! 난 겨우 하나의 작은 문제가 있습니다 : 목적지 좌표는 "근사치"입니다 : 40.380783, 15.541373에 핀이 있다면, long eceed long은 40.3808, 15.5414입니다. – Enzoses

+0

stringURL 형식에서 모든 '% g'을' % f'. – Anna

+0

그리고 이제 완벽 해! 버튼 동작에 대한 마지막 한 가지 : 도달 할 위치의 이름을 각각 표시하기 때문에 둘 이상을 만들었습니다. 더 짧은 길이 있습니까? – Enzoses