【问题标题】:Callout from MKPolylineView?来自 MKPolylineView 的标注?
【发布时间】:2012-03-29 18:49:49
【问题描述】:

当一个人触摸 MKPolylineView 时,有什么方法可以显示标注? 我试图添加一个 UITapGestureRecognizer 并在选择器中显示某个坐标的标注。但没有用。有什么建议吗?

以下是我尝试过的方法

 - (MKOverlayView *)mapView:(MKMapView *)mapa viewForOverlay:(id <MKOverlay>)overlay
        self.polylineView = [[MKPolylineView alloc] initWithPolyline: self.polyline];
        self.polylineView.strokeColor = [UIColor blackColor];
        self.polylineView.lineWidth = 5.0;
        self.polylineView.alpha = 0.7;
        UITapGestureRecognizer *touchOnView = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(addBubble:)];
        [touchOnView setNumberOfTapsRequired:1];
        [touchOnView setNumberOfTouchesRequired:1];
        [self.polylineView addGestureRecognizer:touchOnView];

【问题讨论】:

    标签: ios mkmapview mkannotation mkoverlay


    【解决方案1】:

    非常有趣的问题 - 我什至从未想过将手势识别器放在地图叠加层上。通过一些实验,我已经验证可以检测到对MKPolylineView 的点击。正如您所发现的,点击手势不适用于地图叠加层。因此,我将轻击手势放在MKMapView 而不是MKPolylineView 上。然后处理水龙头:

    - (void)handleTapGesture:(UIGestureRecognizer*)gestureRecognizer
    {
        if (measureLine != nil)
        {
            UIView* hitView = [self.polylineView hitTest:[gestureRecognizer locationInView:self.polylineView] withEvent:nil];
        }
    }
    

    如果您的水龙头在MKPolylineView 之外,hitView 将为 nil,如果水龙头在内部,则为 self.polylineView

    但是,这可能并不如您所愿。对于水平和垂直线,它完美地工作,因为底层视图的大小与线的大小大致相同。但是对于 45 度线,底层视图必须比线大得多,因为它是轴对齐边界框 (AABB)。如果您考虑 45 度线,仅使用水平线和垂直线将其包围起来,您最终会得到一个很大的区域 - 比您想要检测到的敲击要大得多。

    例如

    --------
    |    / |
    |   /  |
    |  /   |
    | /    |
    |/     |
    --------
    

    但是使用点击手势或点击测试将始终导致识别这些 AABB 内的点击。因此,无论您尝试将手势附加到何处 - 例如到MKPolylineViewMKMapView,你会得到虚假的结果。对于较长的线,问题会变得更糟 - 如果您想象一条线从地图视图的右上角到左下角,那么您需要将其包围的 AABB 将覆盖地图视图的整个区域,这意味着点击左上角或右下角将被解释为点击MKPolylineView

    为了解决这个问题,我建议采用以下方法:

    • 在地图视图上使用点击手势识别器
    • 在您处理水龙头的方法中:
      • 将屏幕点击位置转换为地图坐标
      • 循环遍历每条折线(除非您只有 1 条)
      • 对于折线中的每个点,选取将该点连接到下一个点的线段,并计算地图坐标与这条线的距离。使用三角函数来计算。
        • 如果距离非常接近此段,则停止检查其余段并处理您想要显示的任何标注等
        • 如果距离不近,则移动到下一个点以及将其连接到下一个点的线段

    无论多段线的长度或它们的角度如何,都可以保证这种方法有效。没有 AABB 的担忧。缺点是所有这些距离计算可能在计算上很昂贵 - 因此,如果您的折线由大量点组成,或者如果您有大量折线,那么您可能无法进行所有这些计算在不阻止 UI 响应的情况下,这意味着您需要将其移动到后台线程中。如果你只有几条折线,和/或它们由几个点组成,那么你会没事的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多