Выноска из MKPolylineView? - PullRequest
       27

Выноска из MKPolylineView?

4 голосов
/ 29 марта 2012

Есть ли способ показать выноску, когда человек касается 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];

1 Ответ

8 голосов
/ 19 апреля 2012

Очень интересный вопрос - я бы никогда не подумал о том, чтобы поставить распознаватель жестов на наложение карты.Немного поэкспериментировав, я убедился, что можно обнаружить нажатие на MKPolylineView.Как вы уже нашли, жесты касания не работают на наложениях карты.Поэтому вместо этого я ставлю жест касания на MKMapView, а не на MKPolylineView.Затем, чтобы обработать кран:

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

hitView будет равен нулю, если ваш кран был вне MKPolylineView, или будет self.polylineView, если кран был внутри.

Однако , это может работать не совсем так, как вы хотели бы.Для горизонтальных и вертикальных линий это работает идеально, потому что размер базового вида примерно равен размеру линии.Но для линии 45 градусов базовый вид должен быть намного больше, чем линия, потому что это ограничивающий прямоугольник, выровненный по оси (AABB).Если вы думаете о 45-градусной линии, чтобы заключить ее, используя только горизонтальные и вертикальные линии, вы получите большую площадь - гораздо большую, чем вы хотели бы обнаружить в ней.

например

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

Но использование жеста касания или теста попадания всегда приведет к распознаванию касаний внутри этих AABB.Поэтому независимо от того, где вы пытаетесь прикрепить свой жест - например, к MKPolylineView, как вы пытались, или к MKMapView, вы получите ложные результаты.Проблема усугубляется для более длинных линий - если вы представляете линию, идущую от верхнего правого угла вашего вида карты к нижнему левому краю, AABB, который вам нужно будет заключить, охватит всю область вида карты, а это означает, чтонажатие в верхнем левом или нижнем правом углу будет интерпретировано как нажатие MKPolylineView.

. Чтобы решить проблему, я бы предложил следующий подход:

  • Использовать жест касанияраспознаватель на виде карты
  • В вашем методе, который обрабатывает нажатие:
    • преобразует позицию касания экрана в координату карты
    • , проходя по каждой полилинии (если у вастолько 1)
    • для каждой точки ломаной линии, возьмите отрезок, соединяющий эту точку со следующей точкой, и рассчитайте расстояние от вашей карты до координаты этой линии.Используйте тригонометрию, чтобы рассчитать это.
      • , если расстояние очень близко к этому сегменту, тогда прекратите проверку остальных сегментов и обработайте все выноски и т. Д., Которые вы хотели показать
      • , если расстояние не близко, затем перейдите кследующая точка и отрезок, который соединяет ее со следующей, но одной точкой

Этот подход гарантированно работает независимо от длины ваших полилиний,или под каким углом они находятся.Там нет никаких проблем AABB.Недостатком является то, что все эти вычисления расстояний могут быть вычислительно дорогими - поэтому, если ваши полилинии состоят из большого числа точек, или если у вас есть большое количество полилиний, то вы не сможете выполнить все эти вычислениябез блокировки адаптивного интерфейса, то есть вам нужно переместить его в фоновый поток.Если у вас есть только несколько полилиний, и / или они состоят из нескольких точек, то все будет в порядке.

...