自定义地图标注视图在点击时会隐藏

4
我已经制作了自定义地图标注。我的标注包含UIButtonsUITextView。 当我点击UIButton时,它会很好地按下。 但是当我点击UITextView时,它会将光标移动到点击位置,然后取消选择引脚并隐藏标注...
我像这里一样实现了MyAnnotationViewhitTest:withEvent:方法:https://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:

我刚刚使用了一些小技巧实现了我的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

使用此类别在视图层次结构中查找Callout:

@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
1个回答

1
在hitTest方法中,你应该创建一个虚拟矩形来定义可触摸区域,根据你需要触摸的对象。
在UICalloutView中,你应该使用另一个循环来查找你的UITextView。
之后,你应该根据UITextView的尺寸和UICalloutView视图的原点来定义这个虚拟矩形。
此外,在for循环中不需要使用continue语句,因为当return被调用时,所有的循环都会立即停止。
所以你的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;
}

我正在for循环上设置断点,但它从未捕获...我没有使用UICalloutView,我正在使用自己的 - 请查看问题更新。 - k06a
你的代码有误,你把自定义的 CutomCallOutView 添加到了图钉图片下方。你不能直接在 didSelectAnnotationView 方法中添加自定义视图。 看看我的例子,我在 didSelectAnnotationView 中调用另一个名为“findCallOut”的方法。这个方法循环遍历整个地图,直到找到当前打开的 CallOutView 并更改其属性,最后将所需的自定义视图作为子视图添加。如果你隐藏默认泡泡图像和标签等内容, 在找到 UICallOutView 后运行另一个 for 循环来查找要隐藏的子视图。 - ytur
我正在使用单个自定义的弹出视图。我试图将其添加到用户位置点上。在didSelectAnnotationView中,我将弹出视图添加到注释视图中,在didDeselectAnnotationView中,我从父视图中删除弹出视图。现在我正在尝试更改注释视图框架并移动内部层以保持固定在其位置...我遇到了一些问题,但我可以点击我的自定义弹出视图。似乎问题在于弹出视图框架超出了父框架... - k06a

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接