自定义地图标注视图隐藏在自来水中
我制作了自定义贴图标注。 我的标注包含UIButtons
和UITextView
。 当我点击UIButton
,它很好。 但是,当我点击UITextView
它将光标移动到轻击位置,然后取消select引脚和消失标注…
我已经实现了hitTest:withEvent:
方法MyAnnotationView像这里: https hitTest:withEvent:
//stackoverflow.com/a/13495795/440168
但正如我在日志中看到的, [super hitTest:withEvent:]
永远不会返回nil
。
这是我的MyAnnotationView
方法:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { BOOL isInside = [super pointInside:point withEvent:event]; if (isInside) return YES; for (UIView * subview in self.subviews) { if ([subview isKindOfClass:[NSClassFromString(@"UICalloutView") class]]) continue; CGPoint inPoint = [self convertPoint:point toView:subview]; BOOL isInside = [subview pointInside:inPoint withEvent:nil]; if (isInside) return YES; } return NO; } - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView * hitView = [super hitTest:point withEvent:event]; if (hitView) return hitView; for (UIView * subview in self.subviews) { if ([subview isKindOfClass:[NSClassFromString(@"UICalloutView") class]]) continue; CGPoint inPoint = [self convertPoint:point toView:subview]; hitView = [subview hitTest:inPoint withEvent:event]; if (hitView) return hitView; } return nil; }
更新1:
这里是我的代码添加自定义标注视图:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { for (UIView * subview in view.subviews) subview.hidden = YES; [view addSubview:self.myCalloutView]; self.myCalloutView.center = CGPointMake(view.bounds.size.width/2,-self.myCalloutView.bounds.size.height/2); // ... }
更新2:
我刚刚使用durty hack实现了我的MKMapView子类。 但是这个工作!
@implementation HNPMapView - (void)handleTap:(UITapGestureRecognizer *)recognizer { for (UIView * v in [self findSubviewsOfClass:[MyCallout class]]) { CGPoint point = [recognizer locationInView:v]; if (CGRectContainsPoint(v.bounds, point)) return; } //[super performSelector:@selector(handleTap:) withObject:recognizer]; void (*functionPointer)(id,SEL,...) = [MKMapView instanceMethodForSelector:@selector(handleTap:)]; functionPointer(self,@selector(handleTap:),recognizer); } @end
并使用此类别查找视图层次结构中的标注:
@interface UIView (FindSubview) - (NSArray *)findSubviewsOfClass:(Class)class; @end @implementation UIView (FindSubview) - (NSArray *)findSubviewsOfClass:(Class)class { NSMutableArray * found = [NSMutableArray array]; for (UIView * subview in self.subviews) { if ([subview isKindOfClass:class]) [found addObject:subview]; [found addObjectsFromArray:[subview findSubviewsOfClass:class]]; } return found; } @end
在hitTest方法中,您应该创build一个虚拟矩形来根据您的对象定义可触摸的区域。
在UICalloutView你应该使用另一个循环来find你的UITextView。
之后,您应该根据您的UITextView尺寸和UICalloutView查看原点来定义此虚拟矩形。
你也不需要在for循环中使用continue语句,当返回时,所有循环都会立即停止。
所以你的hitTest方法应该是这样的,
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView * hitView = [super hitTest:point withEvent:event]; if (hitView) return hitView; for (UIView * subview in self.subviews) { if ([subview isKindOfClass:[NSClassFromString(@"UICalloutView") class]]) { for(UIView *subTextView in subview.subviews){ if([subTextView isKindOfClass:[UITextView class]]){ CGRect touchableArea = CGRectMake(subview.frame.origin.x, subview.frame.origin.y, subTextView.frame.size.width, subTextView.frame.size.height); if (CGRectContainsPoint(touchableArea, point)){ return subTextView; } } } } } return nil; }