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

Foi útil?

Solução

Eu corri para o mesmo problema, mas não encontrou o que parece ser uma solução confiável e razoável:

  1. 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];
    }
    
  2. 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):

  1. 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.

  2. 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?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top