UIButton未正确加载MKAnnotationView



我正在创建一个带有详细信息披露按钮的MKAnnotationView。

在mapView:viewForAnnotation:我只是创建了一个占位符按钮。

//  the right accessory view needs to be a disclosure button ready to bring up the photo
aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

在mapView:didSelectAnnotationView:我实际上创建了一个要使用的按钮(带有相关标签)

//  create a button for the callout
UIButton *disclosure                = [self.delegate mapController:self buttonForAnnotation:aView.annotation];
NSLog(@"DisclosureButton: %@", disclosure);
//  set the button's target for when it is tapped upon
[disclosure addTarget:self.delegate action:@selector(presentAnnotationPhoto:) forControlEvents:UIControlEventTouchUpInside];
//  make the button the right callout accessory view
aView.rightCalloutAccessoryView = disclosure;

在日志中,按钮似乎已完全实例化,并设置了正确的标记。

这是按钮创建者:

/**
*  returns an button for a specific annotation
*
*  @param  sender              the map controller which is sending this method to us (its' delegate)
*  @param  annotation          the annotation we need to create a button for
*/
- (UIButton *)mapController:(MapController *)   sender
buttonForAnnotation:(id <MKAnnotation>) annotation
{
//  get the annotation as a flickr photo annotation
FlickrPhotoAnnotation *fpa  = (FlickrPhotoAnnotation *)annotation;
//  create a disclosure button used for showing photo in callout
UIButton *disclosureButton      = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//  associate the correct photo with the button
disclosureButton.tag            = [self.photoList indexOfObject:fpa.photo];
return disclosureButton;
}

当我选择注释时,问题就出现了。在选择注释并点击详细信息披露按钮的几秒钟内,什么都没有发生。然而,在离开并返回注释几次并测试按钮后,它最终按预期工作。

奇怪的延误是怎么回事?有时,当按钮开始工作时,它只会显示为alpha设置为0.0,直到你点击它,它才会出现。

说真的,这是我遇到的一个更奇怪的问题。

在调用didSelectAnnotationView委托方法之前,地图视图已经根据注释视图的属性准备好了标注视图(在进行更改之前)。

因此,您在第一次点击时看到的标注没有应用程序在didSelectAnnotationView中所做的更改。在以下抽头上,标注可以基于从上一个抽头设置的值(这实际上取决于在viewForAnnotation中如何处理注释视图重用)。

代码在didSelectAnnotationViewbuttonForAnnotation中所做的似乎只是设置按钮操作和标记。

我假设您使用的是"标记"方法,因为presentAnnotationPhoto:方法需要引用所选注释的属性。

您不需要使用标记来获取操作方法中的选定注释。相反,有几个更好的选择:

  • 您的自定义操作方法可以从地图视图的selectedAnnotations属性中获取选定的注释。请参阅此问题以获取如何执行此操作的示例
  • 使用映射视图自己的委托方法calloutAccessoryControlTapped,而不是自定义操作方法。委托方法传递对注释视图的引用,该视图包含指向其注释的属性(即view.annotation),因此不需要猜测、搜索或询问选择了什么注释。我推荐这个选项

在第一个选项中,在viewForAnnotation中执行addTarget,而不必设置tag。您也不需要buttonForAnnotation方法。然后在按钮操作方法中,从mapView.selectedAnnotations中获取选定的注释。

目前,您的操作方法在self.delegate上,因此您可能在从其他控制器访问地图视图时遇到一些问题。您所能做的是在映射控制器中创建一个本地按钮操作方法,该方法获取选定的注释,然后调用self.delegate上的presentAnnotationPhoto:操作方法(除了现在该方法可以被编写为接受注释参数,而不是按钮点击处理程序)。

第二个选项类似,只是不需要执行任何addTarget,并且在calloutAccessoryControlTapped方法中,在self.delegate上调用presentAnnotationPhoto:

对于这两个选项,我建议修改presentAnnotationPhoto:方法以接受注释对象本身(FlickrPhotoAnnotation *),而不是当前的UIButton *,并在映射控制器中,在方法local上对映射控制器执行addTarget(或使用calloutAccessoryControlTapped),然后从该方法手动调用presentAnnotationPhoto:并将注释传递给它。

最新更新