簡體   English   中英

手勢識別器並非總是會觸發

[英]Gesture Recognizer Not Always Triggered

我試圖使地圖注釋的標注氣泡可點擊(我希望標題可點擊)。 從我所看到的情況來看,沒有很好的方法可以做到這一點,因此我在地圖上實現了手勢識別器,以便可以進行點擊測試以確定是否已點擊標注。 在大多數情況下,它工作正常,但有時手勢識別器無法觸發。

這是我的代碼

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    UITapGestureRecognizer* calloutRecognizer = [[UITapGestureRecognizer alloc]
            initWithTarget:self action:@selector(calloutTapped:)];
    calloutRecognizer.cancelsTouchesInView = false;
    [self.mapView addGestureRecognizer:calloutRecognizer];
}


- (void)calloutTapped:(UITapGestureRecognizer *)gestureRecognizer
{
    CGPoint hitPoint = [gestureRecognizer locationInView:self.mapView];
    UIView *tappedView = [self.mapView hitTest:hitPoint withEvent:nil];
    // This passthrough button ends up consuming events in the callout
    // There seems to be no way to target it explicitly so we must check the class name of the view
    if([NSStringFromClass([tappedView class]) isEqualToString: @"_MKSmallCalloutPassthroughButton"]){
        if(self.mapView.selectedAnnotations.count > 0 ){
            [self clinicTappedForClinic:[self getClinicForAnnotation :self.mapView.selectedAnnotations[0]]];
        }
    }
}

我正在使用iPhone 7模擬器進行測試

有兩種方法可以檢測用戶與注釋視圖的交互。 常見的方法是定義一個標注(你看,當你在一個典型的地圖應用一針一敲這個標准有點酥料餅泡)為您MKAnnotationView 然后,您可以在標准viewForAnnotation方法中為注釋創建注釋視圖:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    return annotationView;
}

這樣,您會收到一個標注,但要添加一個正確的附件,在上面的示例中,它是一個公開指示器。 這樣,他們點擊您的注釋視圖(在上面的示例中為地圖上的大頭針),便會看到該標注,並且當他們點擊該標注的右側附件(此示例中的小顯示指示器)時,就會調用您的calloutAccessoryControlTapped (在下面的示例中,對一些詳細視圖控制器執行segue):

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
// tap action
}

這是在iPhone小屏幕上的一種非常典型的用戶體驗。

但是,如果您不喜歡該UX並且不想使用標准的標注,而是希望發生其他事情,則可以定義MKAnnotationView以便不顯示標注,而是截取它並執行某些操作否則(例如,在iPad Maps應用程序上,您可能會顯示一些更復雜的彈出框,而不是標准的標注)。 例如,您可以讓您的MKAnnotationView不顯示標注:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
    annotationView.canShowCallout = NO;

    return annotationView;
}

但是您可以隨后手動處理didSelectAnnotationView以檢測用戶何時輕按MKAnnotationView ,在此示例中顯示了一個彈出MKAnnotationView

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    [mapView deselectAnnotation:view.annotation animated:YES];

    DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"];
    controller.annotation = view.annotation;
    self.popover = [[UIPopoverController alloc] initWithContentViewController:controller];
    self.popover.delegate = self;
    [self.popover presentPopoverFromRect:view.frame
                                  inView:view.superview
                permittedArrowDirections:UIPopoverArrowDirectionAny
                                animated:YES];
}

如果您嘗試使用UITapGestureRecognizer,則可以參考: 如何捕獲MapView上的水龍頭,然后將其傳遞給默認手勢識別器?

將委托添加到tapGestureRecognizer:

//add <UIGestureRecognizerDelegate> to .h 

//add this where you create tapGestureRecognizer...
tapGestureRecognizer.delegate = self;


// check tapGestureRecognizer working or not properly 
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
    shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM