iPhone: обнаружение касания в MKMapView

Как определить однократное нажатие на экземпляр MKMapView? Должен ли я создать подкласс MKMapView, а затем переопределить метод touchesEnded?

Спасибо,

-Крис


person ChrisJF    schedule 14.08.2009    source источник


Ответы (8)


Надеюсь, это поможет: Как перехватывать события касаний на объектах MKMapView или UIWebView?

person tt.Kilew    schedule 10.11.2009
comment
Да, если вы читаете в комментариях, есть другое решение. На самом деле существует третий способ сделать это (помимо подкласса MKMapView или наложения вашего собственного представления поверх и передачи штрихов в MKMapView). Вместо создания подкласса MKMapView создайте подкласс главного окна и передайте события касания как MKMapView, так и вашему представлению. stackoverflow.com/questions / 1121889 / Еще не пробовал, но, видимо, производительность лучше, и масштабирование пальцем по-прежнему работает. - person ChrisJF; 22.10.2010
comment
эта ссылка больше не действительна - person Pizzaiola Gorgonzola; 04.06.2013

Если вы просто хотите получать уведомления о жестах касания, не влияя на другое сенсорное поведение карты, вам нужно использовать UITapGestureRecognizer. Это очень просто, просто введите такой код.

UITapGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc] 
   initWithTarget:self action:@selector(didTapMap:)];
[theMKMapView addGestureRecognizer:tapRec];
[tapRec release];

Это вызовет didTapMap всякий раз, когда theMKMapView получит жест касания и все щипки, и жесты перетаскивания по-прежнему будут работать, как и раньше.

person pseudopeach    schedule 31.12.2010
comment
Для меня установка селектора не работала, но работала при использовании функций делегата (gestureRecognizerShouldBegin :) Кстати, хотя Tap и Pan работают, UIPinchGestureRecognizer не работает, даже не используя функции делегирования. - person Fede Mika; 23.05.2012
comment
Я не уверен, что сказать вам без каких-либо подробностей, кроме этого ... Использование селектора всегда работает для меня. - person pseudopeach; 25.05.2012
comment
двоеточие отсутствует, ir должно быть @selector(didTapMap:) - person Ali; 25.06.2012
comment
Этот распознаватель жестов также срабатывает, если пользователь дважды нажимает для масштабирования карты или если аннотация выбрана или отменена. Обычно не то, что вы хотите. - person Ortwin Gentz; 14.02.2013

Или, в зависимости от того, что вы пытаетесь сделать, добавьте MKAnnotation (канцелярская кнопка с выноской), чтобы вам было на что нажать - и тогда ваш делегат карты получит событие, например.

mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

person TimM    schedule 18.09.2009

Идеально работает на iOS 8

- (void)viewDidLoad 
    {
        [super viewDidLoad];

        UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:nil];
        doubleTap.numberOfTapsRequired = 2;
        doubleTap.numberOfTouchesRequired = 1;
        [self.mapView addGestureRecognizer:doubleTap];

        UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
        singleTap.numberOfTapsRequired = 1;
        singleTap.numberOfTouchesRequired = 1;
        [singleTap requireGestureRecognizerToFail: doubleTap];
        [self.mapView addGestureRecognizer:singleTap];
     }

   - (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
     {
            if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
                return;
            //Do your work ...
     }
person Sanjeev Rao    schedule 03.04.2015

В настоящее время вы не можете перехватывать касания на виде карты, вы можете попробовать наложить на него непрозрачный вид и посмотреть, улавливает ли он касания ...

person Daniel    schedule 14.08.2009

Просто добавьте фрагмент кода в качестве иллюстрации ответа @ tt-kilew. В моем случае я хочу указать пользователю на себя на карте, но не хочу прерывать его касание перетаскиванием.

@interface PrettyViewController () <MKMapViewDelegate>

@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (assign, nonatomic) BOOL userTouchTheMap;

@end

@implementation PrettyViewController

#pragma mark - UIResponder

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];

    self.userTouchTheMap = [[touches anyObject].view isEqual:self.mapView];
}


#pragma mark - MKMapViewDelegate

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    //We just positioning to user
    if (!self.userTouchTheMap) {
        CLLocationDistance radius = 5000;
        [self.mapView setRegion:MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 2*radius, 2*radius) animated:YES];
    }
}

@end
person WINSergey    schedule 07.04.2017

Ничего из того, что я когда-либо находил, не работало, но я придумал это несовершенное решение: In viewDidLoad

let singleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(onMapClicked))
singleTapRecognizer.delegate = self
mapView.addGestureRecognizer(singleTapRecognizer)

В делегате:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return touch.view!.frame.equalTo(mapView.frame)
}
person Livio    schedule 20.09.2017

мои 2 цента за Swit 5.x:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let v = touch.view
        let ssv = v?.superview?.superview
        if ssv === self.mapView{
            searchBar.resignFirstResponder()
        }
    }
}

оно работает. но честно говоря может сломаться, если яблоко меняет слои просмотров. лучше распознаватель.

person ingconti    schedule 16.09.2019