我有一个自定义的MKAnnotationView 。 在它的setselected:animated方法我添加了一个从笔尖加载的自定义气泡,调整annotationview的框架以包含此视图并用其他颜色重绘注释圆,如下所示(首先 - 未选中,第二选 - 蓝色 - 框架,绿色 - 自定义气泡视图,alpha = 0.8,红色 - 注释视图):
它工作正常,气泡出现,并且只能通过敲击它来“关闭”(这就是为什么我增加了框架)。 我在这个气泡上有一些按钮,如果只有地图注释下没有任何内容,它们都是可点击的。
但是当在标注气泡下有另一个注释我可以点击“穿过”整个气泡。 当我点击其中一个按钮时,会出现点击突出显示,但是因为didSelectAnnotationView会触发,所以会选择其他注释...
我试图让气泡不透明/半透明,没有运气; 在按钮上设置exclusiveTouch,在视图本身上,没有运气; 尽量不要弄乱框架,仍然可以点击。 我错过了什么吗?
谢谢
编辑 : 更短:如果在此UIView下还有其他MKAnnotaionView,为什么我可以点击MKAnnotationView中addSubview中添加的UIView?
细节 :
- (void)setSelected:(BOOL)selected animated:(BOOL)animated { if(selected) { initialFrame = self.frame; // save frame and offset to restore when deselected initialOffset = self.centerOffset; // frame is correct for a circle, like {{2.35, 1.47}, {12, 12}} if (!self.customCallout) { self.customCallout = [[[NSBundle mainBundle] loadNibNamed:@"CustomCallout" owner:self options:nil] objectAtIndex:0]; } // adjust annotationview's frame and center // callout is 200x120, here frame is {{2.35, 1.47}, {200, 132}} self.customCallout.layer.cornerRadius=5; self.customCallout.exclusiveTouch = YES; [self addSubview:self.customCallout]; } ... }It works fine, the bubble appears, and can be "closed" only by tapping outside of it (this is why I've increased the frame). I have some buttons on this bubble and they are clickable if there is nothing under the annotation just the map.
BUT when under the callout bubble there is another annotation I can click "through" the entire bubble. When I tap on one of the buttons, the tap highlight appears, but an other annotation gets selected because the didSelectAnnotationView fires ...
I tried to make the bubble opaque/semitransparent, no luck; set exclusiveTouch on buttons, on the view itself, no luck; tried not to mess with frame, still can click through. Am I missing something ?
Thanks
Edit : Shorter: Why can I click through a UIView added in addSubview in an MKAnnotationView if there is other MKAnnotaionView under this UIView ?
Details :
- (void)setSelected:(BOOL)selected animated:(BOOL)animated { if(selected) { initialFrame = self.frame; // save frame and offset to restore when deselected initialOffset = self.centerOffset; // frame is correct for a circle, like {{2.35, 1.47}, {12, 12}} if (!self.customCallout) { self.customCallout = [[[NSBundle mainBundle] loadNibNamed:@"CustomCallout" owner:self options:nil] objectAtIndex:0]; } // adjust annotationview's frame and center // callout is 200x120, here frame is {{2.35, 1.47}, {200, 132}} self.customCallout.layer.cornerRadius=5; self.customCallout.exclusiveTouch = YES; [self addSubview:self.customCallout]; } ... }initWithAnnotation has these :
self.canShowCallout = NO; // to appear the subview self.exclusiveTouch = YES; // ... self.enabled = YES; self.opaque = YES;最满意答案
触摸处理方法的默认行为(touchesBegan:touchesEnded:等)在文档中有此注释:
此方法的默认实现不执行任何操作。 但是,UIResponder的UIKit子类,特别是UIView,会立即将消息转发到响应者链。
MKAnnotationView是UIVIew的子类。 因此,当您的注释获得触摸时,它会将其传递给它的超类并响应响应者链,因此最终您的地图视图会触摸并激活覆盖的注释。
要解决此问题,请在annotationView类中实现触摸处理方法,并且不要在响应程序链中传递触摸事件。
The default behavior of the touch handling methods (touchesBegan: touchesEnded: etc.) have this note in the documentation:
The default implementation of this method does nothing. However immediate UIKit subclasses of UIResponder, particularly UIView, forward the message up the responder chain.
MKAnnotationView is a subclass of UIVIew. As a result, when your annotation gets a touch, it is passing it to it's super class and on up the responder chain, so eventually you map view gets the touch and activates the covered annotation.
To resolve, implement the touch handling methods in your annotationView class, and do not pass the touch events up the responder chain.
更多推荐
发布评论