地图上重叠注释 (MKAnnotationView) 的问题
在我的 iPhone 应用程序中,我将 MapKit 与 MKMapView 和自定义 MKAnnotationView 结合使用。
问题是当注释在地图上重叠时(在我的应用程序中,注释是照片,这些照片可能会重叠),并且当您点击前面出现的注释时,另一个注释(在背面)接收事件(似乎是随机的) )。
我没有找到任何方法将事件发送到前面的注释。 我不敢相信这个错误/问题没有任何解决方案!
欢迎任何想法(即使是肮脏的解决方案)!
这是我的一些代码(没什么花哨的,很常见):
CustomAnnotation.h
@interface CustomAnnotation : NSObject <MKAnnotation> {
@private
CustomAnnotationView* view;
}
@property (nonatomic, retain) CustomAnnotationView* view;
@end
CustomAnnotation.m
@implementation CustomAnnotation
@synthetize view;
CustomAnnotationView.h
@interface CustomAnnotationView : MKAnnotationView {
}
@end
CustomAnnotationView.m
@implementation CustomAnnotationView
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// Do something related to the annotation tapped
}
@end
主类 ... // 添加了注释,其中一些注释与其他注释重叠。
- (void)addAnnotation:(CustomAnnotation*)annotation {
[map addAnnotation:annotation];
}
...
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
NSString* identifier = getIdentifierFromAnnotation(annotation);
CustomAnnotationView* view;
if(!(view = (CustomAnnotationView*)[map dequeueReusableAnnotationViewWithIdentifier:identifier])) {
view = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: identifier];
[(CustomAnnotation*)annotation setView:view];
[view release];
}
return view;
}
In my iphone application, I'm using MapKit with MKMapView and custom MKAnnotationView.
The problem is when annotations overlap on map (in my app, annotations are photos and those photos may overlap) and when you tap on the annotation that appears on front, it's another annotation (on back) which receives the event (seems to be random).
I didn't find any way to send the event to the front annotation.
I cannot believe this bug/problem doesn't have any solution!
Z ordering and Order of overlapping annotations questions on stackoverflow did not help me that much.
Please any idea is welcome (even dirty solutions)!
Here's some of my code (nothing fancy, very common):
CustomAnnotation.h
@interface CustomAnnotation : NSObject <MKAnnotation> {
@private
CustomAnnotationView* view;
}
@property (nonatomic, retain) CustomAnnotationView* view;
@end
CustomAnnotation.m
@implementation CustomAnnotation
@synthetize view;
CustomAnnotationView.h
@interface CustomAnnotationView : MKAnnotationView {
}
@end
CustomAnnotationView.m
@implementation CustomAnnotationView
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// Do something related to the annotation tapped
}
@end
Main class
... // Annotations are added and some of them overlaps with others.
- (void)addAnnotation:(CustomAnnotation*)annotation {
[map addAnnotation:annotation];
}
...
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
NSString* identifier = getIdentifierFromAnnotation(annotation);
CustomAnnotationView* view;
if(!(view = (CustomAnnotationView*)[map dequeueReusableAnnotationViewWithIdentifier:identifier])) {
view = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: identifier];
[(CustomAnnotation*)annotation setView:view];
[view release];
}
return view;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最后,我发现避免丢失地图功能的最佳方法是:
让 CustomAnnotationView (touchesEnded) 上的触摸侦听器(在每个注释上)
当接收到触摸事件时,将事件传递到主类
主类在注解上循环并保留具有良好位置的注解(触摸事件)在注释框架中)并且在前面
它工作得很好。
Finally, the best way I found and that avoids loosing map funcionalities is to:
let the touch listener on CustomAnnotationView (touchesEnded) (on each annotation)
when receiving touch event, transfer the event to main class
main class loops on annotations and keeps the annotation that has a good location (touch event in the annotation frame) and that is in front
It works pretty well.
查看此问题的解决方案。基本上,您将创建一个透明的 UIView,它将拦截所有触摸。我还没有尝试过,但如果您必须重新实现 MKMapView 中的所有捏合缩放功能,这可能会带来更多麻烦。
如果您有两个(或更多)MKAnnotations 位于同一位置,您可以重复点击以在两者之间切换。这应该可以在不对您的应用程序进行任何更改的情况下工作。
See the solution to this question. Basically you'll create a transparent UIView which will intercept all of the touches. I haven't tried it, but this may be more trouble than it's worth if you have to reimplement all of the pinch-to-zoom functionality in MKMapView.
If you have two (or more) MKAnnotations co-located you can repeatedly tap to toggle between the two. That should work without any changes to your app.
根据 Alexandre 的回答,我禁用了所有自定义 MKAnnotationViews 对象,以便
它们不响应 MKMapView 默认选择行为,并在我的自定义 MKAnnotationView 中实现以下内容:
此解决方案在 iOS 4 上效果很好。似乎禁用 MKAnnotationView不会禁用它的 userInteractionEnabled,而在 iOS 3 上它会禁用。仍在寻找 iOS 3 的解决方案...
编辑:实际上,这似乎是 iOS 4.1 中的一个错误。在 iOS 4.2 中,禁用 pin 也会禁用触摸事件。因此,此方法仅适用于 4.1,也可能适用于 4.0。
Following up on Alexandre's answer, I disabled all my custom MKAnnotationViews objects with
so they don't respond to the MKMapView default select behavior, and implemented in my custom MKAnnotationView the following:
This solution works great on iOS 4. It seems like disabling an MKAnnotationView doesn't disable its userInteractionEnabled, whereas on iOS 3 it does. Still looking for a solution for iOS 3...
EDIT: actually, this seems to be a bug in iOS 4.1. In iOS 4.2, disabling a pin also disables the touch events. Therefore this method only works for 4.1 and possibly 4.0.
我已将 UITapGestureRecognizer 添加到前面的视图中,这为我解决了问题。
在您的情况下,向 CustomAnnotationView 添加手势识别器应该可以解决问题。
I've added the UITapGestureRecognizer to the view at the front and that solved the issue for me.
In your case, adding a gesture recognizer to CustomAnnotationView should solve the issue.