2010-12-08 5 views
3

У меня есть вид на карту с булавками, когда пользователь выбирает штырь, он переходит к подробному экрану для этого вывода. У меня также есть представление таблицы, что, когда пользователь выбирает элемент, он переходит к подробному представлению того же типа.Проблема с аннотацией карты и MKMapView в iOS 4.2?

Вот проблема ...

кажется, работает хорошо во всем от 3.1.3 до 4.1. То есть макет с совпадающими точками. Но у меня есть пользователь, который только что обновился до iOS 4.2 и говорит, что под 4.1 он работал нормально, но в 4.2 выбор штыря выводит его на деталь для другого булавки. Но в представлении таблицы все еще отлично.

Возможно ли, что в iOS 4.2 произошли изменения в MKMapView, который изменяет способ выбора pinID?

Сложение - я добавил соответствующие части viewForAnnotation и checkButtonTapped

- (MKPinAnnotationView *)mapView:(MKMapView *)eMapView viewForAnnotation:(id <MKAnnotation>)annotation { 

int postTag = 0; 

MKPinAnnotationView *pinView = (MKPinAnnotationView *)[eMapView dequeueReusableAnnotationViewWithIdentifier:@"Pin"]; 

if(pinView == nil) { 

    pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"]; 
    pinView.frame = CGRectMake(0, 0, 25, 25); 

} else { 

    pinView.annotation = annotation; 

} 

// Set up the Right callout 
UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
myDetailButton.frame = CGRectMake(0, 0, 23, 23); 
myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 
myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; 

[myDetailButton addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 

// Identify which pin is being selected 
if ([[annotation title] isEqualToString:@"Current Location"]) { 
    postTag = 99999; 
} else { 
    postTag = [annotation getPinID]; 

} 

myDetailButton.tag = postTag; 

pinView.rightCalloutAccessoryView = myDetailButton; 

pinView.animatesDrop = YES; 

// Set to show a callout on the pin 
pinView.canShowCallout = YES; 

return pinView; 
} 

// Method to show detail view when the callOut button is selected 
- (IBAction) checkButtonTapped: (id) sender { 

int nrButtonPressed = ((UIButton *)sender).tag; 

if (nrButtonPressed < 99999) { 
    if (self.showDetailView == nil) { 

     DetailData *tmpViewController = [[DetailData alloc] initWithNibName:@"Detail" bundle:nil]; 
     self.showDetailView = tmpViewController; 
     [tmpViewController release]; 

    } 

    buttonDetail = [[mapView annotations] objectAtIndex:(nrButtonPressed-1)]; 

    NSMutableArray *tmpArray = [NSMutableArray arrayWithObjects: [buttonDetail getDataI], [buttonDetail getDataII], [buttonDetail getDataIII], [buttonDetail getDataIV], [buttonDetail getDataV], nil]; 

    self.showDetailView.eventData = [[NSMutableArray alloc] initWithArray:tmpArray copyItems:YES]; 

    [self.navigationController pushViewController:self.showDetailView animated:YES]; 

    [self.showDetailView.eventData release]; 

} 

}

Как вы можете видеть, в checkButtonTapped я записываю булавку выбранного затем собирать данные из аннотации для этого штифта , Проблема заключается в том, что nrButtonPressed теперь некорректен. Но это прекрасно, если скомпилировано в 4.1.

+0

Показать метод viewNotation и код, который обрабатывает выбор штифта. – Anna 2010-12-08 03:39:31

+0

Я буду рад опубликовать код (его довольно долго), но я не думаю, что это проблема. Причина в том, что я запускаю версию, скомпилированную в 4.1 на iPod Touch, и ее штраф.Я не вносил никаких изменений в viewForAnnotation, и когда я скомпилирован в 4.2, у него есть ошибка в симуляторе (эмуляция iPhone 4.2). Пользователь сказал, что старая версия приложения отлично работает в 4.1, но когда он обновил до версии 4.2 той же версии приложения начали показывать ошибку. Вы все еще хотите код, потому что я опубликую его, если вы это сделаете? – LancDec 2010-12-08 04:56:28

ответ

4

В checkButtonTapped аннотация идентифицируется с помощью тега кнопки. Тег кнопки установлен в viewForAnnotation, вызывая пользовательский метод getPinID.

Тег кнопки используется как индекс в массиве аннотаций mapView. Неясно, как метод getPinID определяет, какой индекс он находится в массиве аннотаций mapView. Я не уверен, что разумно предположить, что аннотация будет иметь определенный индекс в массиве. Даже если mapView не перемешивает аннотации вокруг, ваше приложение может постоянно добавлять и удалять аннотации.

Поскольку вы назначаете кнопку в качестве аксессуара выноски в представлении аннотации, а не используете тег кнопки для идентификации аннотации, вы можете использовать собственный делегат mapView mapView:annotationView:calloutAccessoryControlTapped:.

Вместо того чтобы делать addTarget на кнопке и вызывать свой собственный метод, удалите вызов addTarget и реализуйте calloutAccessoryControlTapped.

В calloutAccessoryControlTapped вы можете напрямую обращаться к аннотации, используя view.annotation. Вы также можете легко проверить, если аннотацию является «местоположение пользователя»:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 
    { 
     if (view.annotation == mapView.userLocation) 
      return; 

     buttonDetail = (MyCustomAnnotationClass *)view.annotation; 

     //show detail view using buttonDetail... 
    } 

Кроме того, в viewForAnnotation, вы создаете кнопку каждый раз, даже если точка зрения используется повторно. Таким образом, повторное использование аннотации, вероятно, заканчивается тем, что накладывает несколько кнопок друг на друга. Кнопка должна быть создана и установлена ​​только в разделе if(pinView == nil).

0

Если кто-то будет заботиться, чтобы увидеть, что я использую сейчас (и это работает) ...

- (MKPinAnnotationView *)mapView:(MKMapView *)eMapView viewForAnnotation:(id <MKAnnotation>)annotation { 

    MKPinAnnotationView *pinView = (MKPinAnnotationView *)[eMapView dequeueReusableAnnotationViewWithIdentifier:@"Pin"]; 

    if(pinView == nil) { 

     pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Pin"]; 
     pinView.frame = CGRectMake(0, 0, 25, 25); 

    } else { 

     pinView.annotation = annotation; 

    } 

    // Set up the Right callout 
    UIButton *myDetailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
    myDetailButton.frame = CGRectMake(0, 0, 23, 23); 
    myDetailButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; 
    myDetailButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter; 

    pinView.rightCalloutAccessoryView = myDetailButton; 

    pinView.animatesDrop = YES; 

    // Set to show a callout on the pin 
    pinView.canShowCallout = YES; 

    return pinView; 
} 

// Added this at the suggestion of aBitObvious on StackOverflow - 120810 
- (void)mapView:(MKMapView *)eMapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { 

    if (view.annotation == eMapView.userLocation) 
     return; 

    if (self.showDetailView == nil) { 

     DetailData *tmpViewController = [[DetailData alloc] initWithNibName:@"DetailData" bundle:nil]; 
     self.showDetailView = tmpViewController; 
     [tmpViewController release]; 

    } 

    buttonDetail = (MyCustomAnnotationClass *)view.annotation; 

    NSMutableArray *tmpArray = [NSMutableArray arrayWithObjects: [buttonDetail getDataI], [buttonDetail getDataII], [buttonDetail getDataIII], [buttonDetail getDataIV], [buttonDetail getDataV], nil]; 

    self.showDetailView.eventData = [[NSMutableArray alloc] initWithArray:tmpArray copyItems:YES]; 

    [self.navigationController pushViewController:self.showDetailView animated:YES]; 

    [self.showDetailView.eventData release]; 

} 

Еще раз спасибо!