Procura-se: Como confiável, consistente selecionar uma anotação MKMapView
-
12-09-2019 - |
Pergunta
Depois de chamar MKMapView 's setCenterCoordinate: animado: método (sem animação), eu gostaria de chamar selectAnnotation: animado: ( com animação), de modo que a anotação salta para fora do pino recém-centrada.
Por enquanto, eu simplesmente prestar atenção para mapViewDidFinishLoadingMap: e selecione a anotação. No entanto, isso é problemático. Por exemplo, este método não é chamado quando não há nenhuma necessidade de carregar dados de mapa adicionais. Nesses casos, a minha anotação não está marcada. :(
Muito bem. Eu poderia chamar isso imediatamente depois de definir a coordenada do centro vez. Ahh, mas, nesse caso, é possível que haja é mapear dados de carga (mas não tem o carregamento terminado ainda). Eu arriscaria chamando-o muito cedo, com a animação se tornar instável no melhor.
Assim, se bem entendi, não é uma questão de saber se o meu coordenada é visível, uma vez que é possível desviar quase uma tela cheia de distância e tem que carregar novos dados do mapa. Em vez disso, é uma questão de saber se as necessidades novo mapa de dados para ser carregado, e depois agir em conformidade.
Algumas ideias sobre como fazer isso, ou como de outra maneira (confiável) seleccionar uma anotação após a re-centrar a ver o mapa na coordenadas onde que vive de anotação?
Clues apreciado - graças
Solução
Eu corri para o mesmo problema, mas não encontrou o que parece ser uma solução confiável e razoável:
-
Implementar a mapView método delegado: didAddAnnotationViews :. Quando eu tentei selecionar a anotação diretamente dentro do método delegado, a chamada caiu com o pino! Isso parecia estranho, então eu adicionar um ligeiro atraso de meio segundo.
-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { [self performSelector:@selector(selectInitialAnnotation) withObject:nil afterDelay:0.5]; }
-
Selecione a anotação inicial como seria de esperar, mas selectAnnotation chamando: animado;
-(void)selectInitialAnnotation { [self.mapView selectAnnotation:self.initialAnnotation animated:YES]; }
Parece que selectAnnotation:animated:
não é chamado em algumas condições. Compare com MKMapView docs :
Se a anotação especificada não está na tela, e, portanto, não faz tem uma vista de anotação associado, este método não tem efeito.
Outras dicas
A forma mais consistente do que usar um tempo limite fixo é ouvir a chamada de retorno regionDidChange
. Situado no centro de coordenadas do mapa para a anotação desejada e quando o método regionDidChange é chamado, em seguida, selecione a anotação no centro, para abrir a chamada.
Aqui está um pouco eu tomei da coisa correr aleatoriamente entre 5 pinos.
Em primeiro lugar, Goto a coordenada do centro da anotação. Digamos que o objeto de anotação é nomeado thePin
.
- (void)someMethod {
[map setCenterCoordinate:thePin.coordinate animated:YES];
}
Em seguida, no método regionDidChange
, selecione essa anotação.
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
[map selectAnnotation:thePin animated:YES];
}
Bem, só FYI, este é o que os médicos dizem,
Se a anotação especificada não está na tela, e, portanto, não faz tem uma vista de anotação associado, este método não tem efeito.
Então, se eu quiser setCenterCoordinate:animated:
chamada ou setRegion:animated:
e, em seguida, eu quero selecionar a anotação chamando, selectAnnotation:animated:
, a anotação não selecionado ea chamada não aparecerá beacause do mesmo motivo exato mencionado no docs, Assim, a maneira que seria ótimo ter algo como, setCenterCoordinate:animated:ComletionBlock
mas não é lá ..! A maneira que funcionou para mim é como abaixo,
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut animations:^{
[self.mapView setCenterCoordinate:location.coordinate animated:YES];
} completion:^(BOOL finished) {
[self.mapView selectAnnotation:location animated:YES];
}];
Isto lhe dará um bloco de conclusão e u pode usar isso para selecionar a anotação.
O que tem trabalhado para mim estava chamando selectAnnotation:animated:
do método mapView:didAddAnnotationViews:
:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
{
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}
documentação da Apple no mesmo aqui
Note que eu só tinha uma anotação no mapa para que [[mapView annotations] lastObject]
foi bom para os meus propósitos. Sua milhagem pode variar.
Eu estava tendo um problema semelhante. Eu estava usando o MKPinAnnotationView padrão com animatesDrop: SIM. Depois eu adicionei as anotações ao MKMapView, eu estava fazendo isso:
[mapView selectAnnotation:[mapView.annotations objectAtIndex:1] animated:YES]
que na lógica do meu programa, deve selecionar a anotação mais próximo. Esta não estava funcionando. Eu descobri a razão: a vista de anotação não estava na tela no momento dessa chamada select, por causa da animação pin queda. Então, tudo que fiz foi definir um temporizador para selecionar a anotação de um segundo mais tarde. É um hack, mas funciona. Eu não tenho certeza se ele vai trabalhar em cada situação, porém, por exemplo, em uma rede 3G vs. 3Gs. Seria melhor para descobrir a função de retorno certo para colocá-lo.
selectTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self
selector:@selector(selectClosestAnnotation) userInfo:nil
repeats:NO];
- (void)selectClosestAnnotation {
[mapView selectAnnotation:[mapView.annotations objectAtIndex:1]
animated:YES];
}
Eu encontrei vários problemas com todas as soluções que eu vi para o meu problema (Eu quero selecionar uma anotação quando eu adicionei-lo de viewDidAppear):
-
Usando o método
mapView:didAddAnnotationViews:
delegado.Isto não funcionou para mim porque, se a anotação especificada não está na tela, e, portanto, não tem uma vista de anotação associado, este método não tem efeito.
-
Usando o método
mapViewDidFinishLoadingMap:
delegado.Isto não funcionou para mim também, porque o mapa é armazenado em cache agora, para o método é chamado apenas uma vez, pela primeira vez.
Solução:
John Blackburn foi muito próximos, mas sem o método mapView:didAddAnnotationViews:
. Eu só chamar de meu método selectAnnotation:
, antes de adicionar a anotação, com um atraso:
[self.mapView addAnnotation:ann];
[self performSelector:@selector(selectAnnotation:) withObject:ann afterDelay:0.5];
E isto é o que eu faço no meu método selectAnnotation:
:
- (void)selectAnnotation:(id < MKAnnotation >)annotation
{
[self.mapView selectAnnotation:annotation animated:YES];
}
Testado em duas iPhone 3GS (iOS 5 e 6) e um iPhone 5.
Eu estava tendo dificuldade semelhante, mas não era realmente capaz de fazer este trabalho método em tudo, muito menos de forma inconsistente.
Aqui está o que eu encontrei para trabalhar. Talvez ele vai trabalhar para você também: Como desencadear vista chamada de MKAnnotationView sem tocar o pino?