Como inicializar MKMapView com uma determinada localização do usuário?
-
08-07-2019 - |
Pergunta
Meu aplicativo conhece a posição do usuário atual (CoreLocation.framework). Assim que o usuário abre uma nova MapView seu iPhone começa a procurar a posição atual novamente. É possível pular essa ou para alterar a primeira posição do usuário para MKMapView?
Editar:
É possível substituir MKMapView e usar um outro LocationManager?
Solução
Sim, é possível ter um objeto do gerente de locação separado e atribuir o seu valor ao mapview (BTW, eu estou usando '=' abaixo como lista de prefixo para evitar que o SO de código formatador de Borking).
= Em seu UIViewController
manter duas propriedades separadas: uma para um MKMapView
e um a um CLLocationManager
.
= Criar um arquivo XIB com o MKMapView
e qualquer outra janela cromo quiser. Ligue as saídas para os propeties controlador. Certifique-se de MKMapView
não segue a localização do usuário.
= Ter o UIViewController implementar o protocolo CLLocationManagerDelegate
- especialmente o método locationManager:didUpdateToLocation:fromLocation:
que será chamado sempre que uma nova localização valor está disponível. Nós estaremos definindo o controlador como o delegado para a locação.
= No método loadView
do viewController, carregue o NIB com o MKMapView
nele. Para dar feedback do usuário que você pode querer colocar um spinner UIActivityIndicatorView
e configurá-lo para startAnimating
. Então você começa com:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
self.locationManager.distanceFilter = 10; // or whatever
[self.locationManager startUpdatingLocation];
= Na verificação locationManager:didUpdateToLocation:fromLocation:
para ver se o evento foi atualizado desde os últimos N segundos. Então diga o gerente local para atualização de parada, o botão rotativo para animação stop, e obter os dados de latitude / longitude e atribuí-lo ao ver no mapa juntamente com uma extensão de vista e região para que ele amplia e centros para o lugar certo.
= Agora aqui é a parte complicada: o mármore 'throbber' azul é uma característica da localização do usuário de rastreamento mapview. Você vai ter que momentaneamente 'fingir' até que o verdadeiro entra em ação (ou apenas usar um marcador separado para a localização atual e manter sua posição de si mesmo). Pessoalmente, eu iria com o mármore azul que o usuário está familiarizado.
= Para torná-lo para que ele mostre direita na inicialização que você precisará criar um MKAnnotationView personalizado com apenas o gráfico mármore azul adicionado no local retornado pela locação. Isto significa tomar um instantâneo de um mapView com a exibição local, então photoshopping apenas o mármore azul para fora e usá-lo como a imagem para uma vista de anotação personalizado.
= Se você quiser que ele siga ativamente o mapa, você pode ativar o rastreamento userlocation do mapview e quando chega os dados reais, você esconde o seu marcador previamente definido e deixar o mapview fazer a atualização. A outra opção é permitir que o gerente local existente para continuar a receber atualizações a cada segundo ou assim e atualizar a posição do azul anotação mármore si mesmo.
= Para deixar próprio userLocation do mapview fazer o add atualização para viewDidLoad:
[self.map.userLocation addObserver:self
forKeyPath:@"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:NULL];
self.map.showsUserLocation = YES; // starts updating user location
= Implementar observeValueForKeyPath
. Ele é chamado quando o atributo location
de userlocation
do mapview tem um valor:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([self.map isUserLocationVisible]) {
[self.locationManager stopUpdatingLocation];
self.ownBlueMarble.hidden = YES;
}
// The current location is in self.map.userLocation.coordinate
}
= Para evitar o atraso de aquecimento em mostrando a localização atual, manter uma referência para o viewController contendo o mapa eo gerente de locação para que ele não vá embora (que é um pouco de um devorador de memória, mas se você soltá-lo você vai ter que esperar novamente até MapView carrega as telhas e está pronto para ir).
= Em viewWillLoad
você pode encher a última localização conhecida para a anotação bluemarble personalizado e mostrá-lo. Ativar / desativar o rastreamento userLocation e quando você começa a notificação o mesmo truque hide-a-anotação-show-the-real-mármore vai funcionar. Do MapView próprias gerente de locação entra em ação e quando se tem os dados, você pode fazer o seu marcador anotação desaparecer.
= Você pode querer implementar o método viewWillDisappear
do viewController e manualmente desativar o rastreamento userLocation
na mapview por isso é desativado por padrão na próxima vez que a visão é levantada. Você também vai querer obter a última userLocation
conhecido e guardá-lo para a próxima get-go. Dessa forma, você pode fazer tudo o posicionamento marcador de malabarismo no método viewWillAppear
e não precisa se preocupar com userLocation interferir até que você esteja pronto para isso.
Boasorte.
Outras dicas
Em seu controlador:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CLLocationCoordinate2D coord = {latitude: 37.423617, longitude: -122.220154};
MKCoordinateSpan span = {latitudeDelta: 1, longitudeDelta: 1};
MKCoordinateRegion region = {coord, span};
[mapView setRegion:region];
}
Quando mapa é apresentado que vai ser centrada perto de Palo Alto
Tente definir a propriedade showUserLocation
para false na inicialização e, em seguida, restaurar o region
a visualização do mapa anteriormente tinha (você obviamente tem que armazenar isso antes do mapa anterior é destruído).
É isso que você queria?
Você não precisa usar outro Location Manager, você pode adicionar o que pontos você quer o mapa e atualizá-los via qualquer outra lógica que você deseja.
Vamos dizer que você tinha uma conexão de soquete para um carro de controle remoto, e que os dados de socket carro enviar de volta com informação geo-localização na carga útil. Você pôde analisar isso e atualizar a localização da miniatura em seu mapa em tempo real. A propriedade "userLocation" não é necessário para isso, mas você pode mostrá-lo se você quiser.
A localização do usuário é somente leitura, você pode usá-lo ou não. Isso não significa que você precisa de outra locação para fazer qualquer coisa que você pode precisar fazer. Parece que a sua aplicação não precisa realmente esse recurso, mas eu poderia ser mal-entendido a sua pergunta.