Проблема с аннотацией карты и MKMapView в iOS 4.2? - PullRequest
3 голосов
/ 08 декабря 2010

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

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

Кажется, что он отлично работает во всем, начиная с 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

Ответы [ 2 ]

4 голосов
/ 08 декабря 2010

В 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 голосов
/ 09 декабря 2010

Если кому-то захочется посмотреть, что я использую сейчас (и оно работает) ...

- (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];

}

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

...