iOS 4.2 中的地图注释和 MKMapView 存在问题?

发布于 2024-10-06 12:56:30 字数 2723 浏览 0 评论 0原文

我有一个带有图钉的地图视图,当用户选择图钉时,它会转到该图钉的详细信息屏幕。我还有一个表视图,当用户选择一个项目时,它会进入相同类型的详细视图。

问题是......

它似乎在 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下编译就可以了

I have a map view with pins that when the user selects a pin it goes to a detail screen for that pin. I also have a table view that when the user selects an item it goes to the same type detail view.

Here's the problem ...

It seems to work fine in everything from 3.1.3 to 4.1. That is the detail view matches with the pin. But I have a user who just upgraded to iOS 4.2 and says that under 4.1 it worked fine, but in 4.2 the pin selection takes him to the detail for a different pin. But in the table view it still works fine.

Is it possible that there was a change in MKMapView in iOS 4.2 that changes how the pinID is selected?

Addition - I have added the relevant parts of viewForAnnotation and 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];

}

}

As you can see, in checkButtonTapped I record the pin selected then collect the data from the annotation for that pin. The problem seems to be that nrButtonPressed is now incorrect. But it is fine when compiled in 4.1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世俗缘 2024-10-13 12:56:30

在 checkButtonTapped 中,注释是使用按钮的标签来标识的。通过调用自定义方法 getPinID 在 vi​​ewForAnnotation 中设置按钮的标签。

按钮标签用作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) 部分创建和设置。

In checkButtonTapped, the annotation is being identified using the button's tag. The button's tag is set in viewForAnnotation by calling the custom method getPinID.

The button tag is used as the index into the mapView annotations array. It's not clear how the getPinID method figures out what index it is at in the mapView's annotations array. I'm not sure it's wise to assume an annotation is going to be at a specific index in the array. Even if mapView doesn't shuffle the annotations around, your app might be constantly adding and removing annotations.

Because you are assigning the button as a callout accessory in the annotation view, rather than using a button tag to identify the annotation, you can use the mapView's own mapView:annotationView:calloutAccessoryControlTapped: delegate method.

Instead of doing addTarget on the button and having it call your custom method, remove the call to addTarget and implement calloutAccessoryControlTapped.

In calloutAccessoryControlTapped, you can directly access the annotation using view.annotation. You can also easily check if the annotation is the "user location":

 - (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...
    }

Additionally, in viewForAnnotation, you are creating a button every time even if the view is being re-used. So a re-used annotation view probably ends up getting multiple buttons on top of each other. The button should only be created and set in the if(pinView == nil) section.

会发光的星星闪亮亮i 2024-10-13 12:56:30

如果有人愿意看看我现在使用的是什么(并且它正在工作)......

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

}

再次感谢!

If anyone would care to see what I am using now (and it is working) ...

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

}

Thanks again!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文