iOS 4.2中地图标注和MKMapView出现问题?

3
我有一个地图视图,并且在用户选择一根插针时会进入该插针的详细信息页面。我还有一个表格视图,当用户选择项目时也会进入相同类型的详细信息视图。
问题是...
它似乎在从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函数中,我记录了所选的pin,然后收集该pin的注释数据。问题似乎在于nrButtonPressed现在不正确了。但是在4.1版本中编译时没有问题。


展示 viewForAnnotation 方法和处理标记选择的代码。 - user467105
我很乐意发布代码(只是有点长),但我认为问题不在于此。原因是我在iPod Touch上运行了一个在4.1编译的版本,它很好用。我没有对viewForAnnotation进行任何更改,当我在4.2中编译时,在模拟器(模拟iPhone 4.2)中出现了错误。用户说旧版本的应用在4.1中运行良好,但当他升级到4.2时,同一版本的应用程序开始显示错误。如果您仍然需要代码,我会发布它。 - LancDec
如果代码非常长且复杂,您需要进行一些调试并隔离可能出现问题的区域。尝试在单独的小项目中重现问题。苹果公司的发布说明中唯一关于4.2 MapKit的区别是有关处理注释视图重用的(请参见“注释和已知问题”下的MapKit条目)。这可能与您相关。 - user467105
2个回答

4
在checkButtonTapped方法中,使用按钮的标签来识别注释。按钮的标签是通过调用自定义方法getPinID在viewForAnnotation中设置的。
按钮标签用作mapView注释数组的索引。不清楚getPinID方法如何确定它在mapView注释数组中的索引。假设注释将在数组中具有特定的索引可能不明智。即使mapView没有打乱注释的顺序,您的应用程序可能会不断添加和删除注释。
因为您将按钮分配为注释视图中的callout附件,而不是使用按钮标记标识注释,所以可以使用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)部分中创建并设置。

非常感谢。我使用calloutAccessoryControlTapped进行了更改,现在它可以工作了。我做了一个小小的补充,现在看起来很明显,但一个小时前并没有想到。在calloutAccessoryControlTapped方法中,我需要在buttonDetail之前添加initWithNibName。 - LancDec

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

}

再次感谢!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接