핀을 건드리지 않고 MKAnnotationView의 콜 아웃 뷰를 트리거하는 방법은 무엇입니까?
나는 MKMapView
위치 포인트로 일반적인 컬러 핀을 사용하여 작업하고 있습니다. 핀을 건드리지 않고 콜 아웃을 표시하고 싶습니다.
어떻게해야합니까? setSelected:YES
annotationview를 호출해도 아무 작업도 수행되지 않았습니다. 핀 터치를 시뮬레이션하려고하는데 어떻게해야할지 모르겠습니다.
그러나 benvolioT의 솔루션이 작동하도록하는 데에는 문제가 있습니다.
for (id<MKAnnotation> currentAnnotation in mapView.annotations) {
if ([currentAnnotation isEqual:annotationToSelect]) {
[mapView selectAnnotation:currentAnnotation animated:FALSE];
}
}
에서 호출해야하며 - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
다른 곳에서는 호출하지 않아야합니다 .
시퀀스가있는 다양한 방법이 좋아 viewWillAppear
, viewDidAppear
의 UIViewController
상기 - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
호출이 맵이 하나 개의 특정 위치와지도가 동일한 위치에 표시되는 이후 시간으로 처음로드 사이에 상이하다. 이것은 약간 까다 롭습니다.
이 문제에 대한 해결책이 있습니다.
콜 아웃을 표시하려면 MKMapView
의 selectAnnotation:animated
방법을 사용하십시오.
마지막 주석보기를 선택하기를 원한다고 가정하면 아래 코드를 입력 할 수 있습니다.
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
아래 대리자에서 :
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
//Here
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}
좋아, 콜 아웃을 성공적으로 추가하려면 델리게이트의 didAddAnnotationViews를 사용하여 모든 주석보기가 추가 된 후 selectAnnotation : animated를 호출해야합니다.
- (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)anObject
클래스가 구현하는 것을 MKAnnotation 프로토콜.
마지막으로 추가 한 주석에 대한 설명 선을 열려면 이것을 시도해보십시오.
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
API를주의 깊게 읽고 마침내 문제를 발견했습니다.
지정된 주석이 화면에 표시되지 않아 관련 주석보기가없는 경우이 방법은 효과가 없습니다.
따라서 잠시 기다린 후 (예 : 3 초)이 작업을 수행 할 수 있습니다. 그런 다음 작동합니다.
selectAnnotation
from 호출의 문제 - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
는 이름에서 알 수 있듯이이 이벤트는 MapView가 처음로드 될 때만 트리거되므로 MapView가로드를 마친 후에 주석을 추가하면 주석의 콜 아웃을 트리거 할 수 없다는 것입니다.
에서 호출 할 때의 문제는를 호출 할 - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
때 주석이 화면에 표시되지 않아 selectAnnotation
아무 효과가 없다는 것입니다. 주석을 추가하기 전에 MapView의 영역을 주석의 좌표에 중앙에 배치하더라도 selectAnnotation
주석이 화면에 표시되기 전에 MapView의 영역을 설정하는 데 걸리는 약간의 지연이 충분합니다 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 지역과 새로운 지역 사이의 거리 또는 인터넷 연결 속도와 같은 다양한 요인에 따라 주석이 화면에 표시되는 데 1 초 이상 걸릴 수 있으므로 이상한 결과를 얻을 수 있습니다.
I decided to make the call from - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
instead since it ensures the annotation is actually on-screen (assuming you set your MapView's region to your annotation's coordinate) because this event is triggered after setRegion
(and its animation) has finished. However, regionDidChangeAnimated
is triggered whenever your MapView's region changes, including when the user just pans around the map so you have to make sure you have a condition to properly identify when is the right time to trigger the annotation's callout.
Here's how I did it:
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;
}
}
That way your annotation is guaranteed to be on-screen at the moment selectAnnotation
is called, and the if (myAnnotationWithCallout)
part ensures no region setting other than the one in - (void)someMethod
will trigger the callout.
Due to something like the code shown by benvolioT, that I suspect exists in the system, when I used selectAnnotation:animation: method, it did not show the callOut, I guessed that the reason was because it was already selected and it was avoiding from asking the MapView to redraw the callOut on the map using the annotation title and subtitle.
So, the solution was simply to deselect it first and to re-select it.
E.g: First, I needed to do this in Apple's touchMoved method (i.e. how to drag an AnnotationView) to hide the callOut. (Simply using annotation.canShowAnnotation = NO alone does not work, since I suspect that it needs redrawing. The deselectAnnotaiton causes the necessary action. Also, deselecting alone did not do that trick, the callOut disappeared only once and got redrawn straight away. This was the hint that it got reselected automatically).
annotationView.canShowAnnotation = NO;
[mapView deselectAnnotation:annotation animated:YES];
Then, simply using the code below in touchEnded method did not bring back the callOut (The annotation has been automatically selected by the system by that time, and presumably the redrawing of the callOut never occrrs):
annotationView.canShowAnnotation = YES;
[mapView selectAnnotation:annotation animated:YES];
The solution was:
annotationView.canShowAnnotation = YES;
[mapView deselectAnnotation:annotation animated:YES];
[mapView selectAnnotation:annotation animated:YES];
This simply bought back the callOut, presumably it re-initiated the process of redrawing the callOut by the mapView.
Strictly speaking, I should detect whether the annotation is the current annotation or not (selected, which I know it is) and whether the callOut is actually showing or not (which I don't know) and decide to redraw it accordingly, that would be better. I, however, have not found the callOut detection method yet and trying to do so myself is just a little bit unnecessary at this stage.
Steve Shi's response made it clear to me that selectAnnotation has to be called from mapViewDidFinishLoadingMap method. Unfortunately i cannot vote up but i want to say thanks here.
Just add [mapView selectAnnotation:point animated:YES];
Resetting the annotations also will bring the callout to front.
[mapView removeAnnotation: currentMarker];
[mapView addAnnotation:currentMarker];
'Development Tip' 카테고리의 다른 글
실행 시간이없는 루프 (0) | 2020.10.20 |
---|---|
페이드 인 및 추가 사용 (0) | 2020.10.20 |
인덱스 배열 위치가 0이 아닌 다른 일반적인 "c 유사"또는 비 "c 유사"언어가 있습니까? (0) | 2020.10.20 |
불변 목록에서 한 요소를 "제거"하는 관용적 스칼라 방식은 무엇입니까? (0) | 2020.10.20 |
두 번째 원격 호스트로 scp하는 방법 (0) | 2020.10.20 |