source

핀을 터치하지 않고 MKnotationView의 콜아웃 뷰를 트리거하는 방법은 무엇입니까?

manycodes 2023. 8. 24. 22:16
반응형

핀을 터치하지 않고 MKnotationView의 콜아웃 뷰를 트리거하는 방법은 무엇입니까?

▁a▁on를 작업하고 있습니다.MKMapView일반적인 색상의 핀을 위치 포인트로 사용합니다.핀을 만지지 않고 콜아웃을 표시할 수 있으면 좋겠습니다.

어떻게 해야 하나요?하기 르기setSelected:YES주석 보기에서 아무 것도 하지 않았습니다.핀 터치 시뮬레이션을 해볼까 하는데 어떻게 해야 할지 모르겠어요.

하지만 벤볼리오T의 해결책인 코드를 얻기 위한 함정이 있습니다.

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}

에서 야합니다어되출에서 불러야 합니다.- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView그리고 다른 곳은 없습니다.

다한방법좋들이순서아는하양▁▁methods순과 같은 다양한 이 나오는 입니다.viewWillAppear,viewDidAppearUIViewController 리고그고.- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView호출은 맵이 하나의 특정 위치로 처음 로드될 때와 이후에 맵이 동일한 위치로 표시될 때 사이에 다릅니다.이거 좀 까다롭네요.

자, 여기 이 문제에 대한 해결책이 있습니다.

하려면 호출사표방을 합니다.MKMapViewselectAnnotation:animated방법.

마지막 주석 보기를 선택할 경우 아래에 코드를 넣을 수 있습니다.

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];

아래 대리인:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    //Here
    [mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}

좋아요. 콜아웃을 성공적으로 추가하려면 대리자의 didAddAnnotationViews를 사용하여 Annotation: 모든 주석 뷰가 추가된 후 애니메이션을 선택합니다.

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{
    for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
        if ([currentAnnotation isEqual: annotationToSelect]) {
            [mapView selectAnnotation:currentAnnotation animated:YES];
        }
    }
}

이 스레드에 대한 다양한 답을 시도한 후, 저는 마침내 이것을 생각해냈습니다.매우 안정적으로 작동합니다. 아직 실패한 것을 보지 못했습니다.

- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views;
{
    for(id<MKAnnotation> currentAnnotation in aMapView.annotations) 
    {       
        if([currentAnnotation isEqual:annotationToSelect]) 
        {
            NSLog(@"Yay!");
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_current_queue(), ^
            {
                [aMapView selectAnnotation:currentAnnotation animated:YES];
            });
        }
    }
}

블록이 없으면 콜아웃이 올바르게 표시되지 않을 수 있으므로 블록은 약간 지연되는 데 사용됩니다.

이것은 저에게 효과가 없습니다.MapKit API에 버그가 있는 것 같습니다.

작동하지 않는 다른 사용자에 대한 자세한 내용은 다음 링크를 참조하십시오. http://www.iphonedevsdk.com/forum/iphone-sdk-development/19740-trigger-mkannotationview-callout-bubble.html#post110447

--편집--

좋아요, 한동안 이것을 가지고 놀다가, 제가 할 수 있었던 일은 다음과 같습니다.

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}

참고, 이를 위해서는 다음을 구현해야 합니다.- (BOOL)isEqual:(id)anObjectMK 주석 프로토콜을 구현하는 클래스에 해당합니다.

마지막으로 추가한 주석에 대한 콜아웃을 열고 싶다면, 이것을 사용해 보십시오. 저에게 도움이 됩니다.

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];

에 전화하는 .selectAnnotation- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView 알 수 이 처음 가 완료된 후 수 없습니다."라는 의미입니다.

전화를 걸 때의 문제는- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views다음과 같은 경우 주석이 화면에 표시되지 않을 수 있습니다.selectAnnotation이 호출되어 아무런 영향을 미치지 않습니다.하는 데 합니다.selectAnnotation만들 에 호출됩니다.setRegion.

어떤 사람들은 전화로 이 문제를 해결했습니다.selectAnnotation다음과 같이 지연된 후:

-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    [self performSelector:@selector(selectLastAnnotation)
        withObject:nil afterDelay:1];
}

-(void)selectLastAnnotation {
    [myMapView selectAnnotation:
        [[myMapView annotations] lastObject] animated:YES];
}

그러나 이전 MapView 영역과 새 MapView 영역 간의 거리 또는 인터넷 연결 속도와 같은 다양한 요인에 따라 주석이 화면에 표시되는 데 1초 이상 걸릴 수 있으므로 이상한 결과가 나타날 수 있습니다.

는 전를걸했습다에서 로 결정했습니다.- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated대신 이 이벤트는 다음 시간 이후에 트리거되므로 주석이 실제로 화면에 표시됩니다(MapView의 영역을 주석의 좌표로 설정했다고 가정). setRegion(및 애니메이션)이 완료되었습니다. 하만지,regionDidChangeAnimated사용자가 지도 주위를 이동하기만 하면 주석의 호출을 트리거할 수 있는 적절한 시기를 식별할 수 있는 조건을 갖추고 있어야 하는 경우를 포함하여 MapView의 영역이 변경될 때마다 트리거됩니다.

제가 한 방법은 다음과 같습니다.

MKPointAnnotation *myAnnotationWithCallout;

- (void)someMethod {
    MKPointAnnotation *myAnnotation = [[MKPointAnnotation alloc] init];
    [myAnnotation setCoordinate: someCoordinate];
    [myAnnotation setTitle: someTitle];

    MKCoordinateRegion someRegion =
       MKCoordinateRegionMakeWithDistance (someCoordinate, zoomLevel, zoomLevel);

    myAnnotationWithCallout = myAnnotation;
    [myMapView setRegion: someRegion animated: YES];
    [myMapView addAnnotation: myAnnotation];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    if (myAnnotationWithCallout)
    {
        [mapView selectAnnotation: myAnnotationWithCallout animated:YES];
        myAnnotationWithCallout = nil;
    }
}

이 그 에 화면에 주석이 표시됩니다.selectAnnotation, 이호되고고, 그리출고.if (myAnnotationWithCallout)부품은 의 영역 설정 이외의 영역 설정을 보장하지 않습니다.- (void)someMethod호출을 트리거합니다.

API를 자세히 읽어보니 문제가 있었습니다.


지정한 주석이 화면에 표시되지 않아 관련 주석 보기가 없는 경우 이 방법은 아무런 영향을 받지 않습니다.

따라서 시간(예: 3초)을 기다린 후 이 작업을 수행할 수 있습니다.그러면 효과가 있습니다.

benvolioT에 의해 표시된 코드와 같은 이유로 시스템에 존재하는 것으로 의심됩니다. selectAnnotation:animation:method를 사용했을 때 callOut이 표시되지 않았습니다. 이유는 이미 선택되었기 때문이며 주석 제목과 부제를 사용하여 맵 뷰에 callOut을 다시 그리도록 요청하는 것을 피하고 있었기 때문이라고 추측했습니다.

그래서 해결책은 먼저 선택을 취소하고 다시 선택하는 것이었습니다.

예: 먼저, 호출Out을 숨기기 위해 Apple의 touchMoved 메서드(즉, AnnotationView를 끄는 방법)에서 이 작업을 수행해야 했습니다. (단순히 주석을 사용하여 .canShowAnnotation = NO 단독으로 작업할 수 없습니다. 왜냐하면 다시 그리기가 필요할 것으로 예상되기 때문입니다.Annotiton을 선택 취소하면 필요한 작업이 발생합니다.또한, 선택을 취소하는 것만으로는 이러한 트릭을 수행하지 못했으며, callOut은 단 한 번만 사라지고 바로 다시 그려졌습니다.이것은 자동으로 다시 선택되었음을 암시합니다.

annotationView.canShowAnnotation = NO;
[mapView deselectAnnotation:annotation animated:YES];

그런 다음 단순히 아래 코드를 터치엔드 방식으로 사용해도 callOut이 반환되지 않습니다(주석은 그때까지 시스템에 의해 자동으로 선택되었으며, 아마도 callOut의 재도면은 발생하지 않을 것입니다).

annotationView.canShowAnnotation = YES;
[mapView selectAnnotation:annotation animated:YES];

솔루션은 다음과 같습니다.

annotationView.canShowAnnotation = YES;
[mapView deselectAnnotation:annotation animated:YES];
[mapView selectAnnotation:annotation animated:YES];

이것은 단순히 callOut을 다시 샀을 뿐이며, 아마도 mapView에 의해 callOut을 다시 그리는 프로세스를 다시 시작했을 것입니다.

엄밀히 말하면, 나는 주석이 현재 주석인지 아닌지(선택되었는지, 내가 알고 있는 것)와 callOut이 실제로 표시되는지(모르는 것)를 감지하고 그에 따라 다시 그리기로 결정해야 합니다.하지만, 저는 아직 callOut 감지 방법을 찾지 못했고, 이 단계에서 제 자신이 그렇게 하려고 하는 것은 조금 불필요합니다.

Steve Shi의 응답은 mapViewDidFinishLoadingMap 메서드에서 주석을 호출해야 한다는 것을 분명히 했습니다.유감스럽게도 저는 투표를 할 수 없지만 여기서 감사하다고 말하고 싶습니다.

[mapView selectAnnotation: 포인트 애니메이션:]을 추가하기만 하면 됩니다.예];

주석을 재설정하면 콜아웃도 앞으로 나오게 됩니다.

    [mapView removeAnnotation: currentMarker];
    [mapView addAnnotation:currentMarker];

언급URL : https://stackoverflow.com/questions/978897/how-to-trigger-mkannotationviews-callout-view-without-touching-the-pin

반응형