自定义地图标注视图隐藏在水龙头上 [英] Custom map callout view hides on tap

查看:58
本文介绍了自定义地图标注视图隐藏在水龙头上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经进行了自定义地图标注.我的标注包含UIButtonsUITextView.当我点击UIButton时,它按的很好.但是,当我点击UITextView时,它将光标移至点击位置,然后取消选择图钉并消失标注...

I've made custom map callouts. My callouts contains UIButtons and UITextView. When I tap UIButton, it presses nice. But when I tap UITextView it moves cursor to tap position and then deselects pin and disappears callout...

我已经实现了MyAnnotationView的hitTest:withEvent:方法,如下所示: https://stackoverflow.com/a/13495795/440168

I've implemented hitTest:withEvent: method of MyAnnotationView like here: https://stackoverflow.com/a/13495795/440168

但是正如我在日志中看到的那样,[super hitTest:withEvent:]从不返回nil.

But as I see in log, [super hitTest:withEvent:] never returns 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:

这是我的代码,用于添加自定义标注视图:

Here is my code to add custom callout view:

- (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子类.但这行得通!

I have just implemented my MKMapView subclass with durty hack. But this works!

@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

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

And using this category to find callout in view hierarchy:

@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方法中,您应该创建一个虚拟矩形以根据要触摸的对象定义可触摸区域.

in hitTest method you should create a virtual rectangle to define touchable area according to your object to be touchable.

在UICalloutView中,您应该使用另一个循环来找到您的UITextView.

in UICalloutView you should use another loop to find your UITextView.

之后,您应该根据UITextView尺寸和UICalloutView视图原点定义此虚拟矩形.

after that you should define this virtual rectangle according your UITextView dimensions and UICalloutView view origin points.

您也不需要在for循环中使用continue语句, 返回启动时,所有循环将立即停止.

also you don't need to use continue statement in for loop, when return initiated all loops will stop immediately already.

所以您的hitTest方法应该是这样的,

so your hitTest method should be like this,

- (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;
}

这篇关于自定义地图标注视图隐藏在水龙头上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆