12 Ago, 2013 12:38
Utilizando o Google Maps no seu Aplicativo iOS - Parte 2
InfoWindow padrão
A InfoWindow padrão é muito simples de usar. Basta você definir as propriedades title e snippet do GMSMarker, ex:
GMSMarker *mobits = [GMSMarker markerWithPosition:CLLocationCoordinate2DMake(-22.90644,-43.177171)];
mobits.title = @"Mobits";
mobits.snippet = @"Ideias para um mundo móvel";
mobits.map = self.mapView;
mobits.icon = [GMSMarker markerImageWithColor:[UIColor clearColor]];
Quando o usuário tocar no marcador definido acima, o próprio SDK fará todo o tratamento necessário para mostrar uma InfoWindow como abaixo.
Alterando a aparência da InfoWindow padrão
Se o visual acima não atende às suas expectativas, é possível substituir a UIView utilizada pelo SDK por uma criada por você.
O primeiro passo é definir o seu controller como delegate do seu mapa:
self.mapView.delegate = self;
Em seguida, crie uma UIView ou subclasse no seu XIB ou programaticamente e implemente o método de GMSMapViewDelegate de maneira semelhante a abaixo.
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
self.tituloLabel.text = marker.title;
self.subtituloLabel.text = marker.snippet;
return self.myInfoWindowView;
}
O resultado será parecido com este:
OBS: Como você pode ver, a UIView acima não recebe as sombras nem a seta para baixo presentes na InfoWindow padrão. É sua responsabilidade preparar os elementos visuais que você quiser que apareçam.
Interagindo com a InfoWindow
O SDK permite detectar quando o usuário tocar na InfoWindow para poder executar ações em resposta. Para isso, basta implementar o método de GMSMapViewDelegate abaixo:
- (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"InfoWindow" message:@"Tocou na InfoWindow" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
Desta maneira simples, teremos o resultado:
A solução acima funciona tanto com a InfoWindow padrão quanto com a personalizada.
Substituindo completamente a InfoWindow
Apesar de você poder detectar o toque na InfoWindow, não é possível realizar outras interações com ela, como, p. ex., colocar botões dentro da InfoWindow para o usuário realizar diversas ações. O motivo é que o SDK renderiza da UIView em uma imagem que não permite interações ou animações.
Se você precisa de recursos mais avançados, terá que implementar sua própria InfoWindow e tratar a exibição, posicionamento e interações por sua conta. Observe o código abaixo:
- (void)viewDidLoad {
...
self.myInfoWindowView.hidden = YES;
[self.mapView addSubview:self.myInfoWindowView]; // A
...
}
#pragma mark - GMSMapViewDelegate
- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
self.myInfoWindowView.hidden = NO; // B
self.tituloLabel.text = marker.title;
self.subtituloLabel.text = marker.snippet;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithTarget:marker.position
zoom:10];
[mapView setCamera:camera]; // C
markerSelecionado = marker;
[self posicionaInfoWindowView]; // D
return YES; //E
}
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
self.myInfoWindowView.hidden = YES; // F
markerSelecionado = nil;
}
- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position {
if (!self.myInfoWindowView.hidden) {
[self posicionaInfoWindowView]; // G
}
}
#pragma mark - Private
- (void)posicionaInfoWindowView {
CGPoint pontoNaMapView = [self.mapView.projection pointForCoordinate:markerSelecionado.position];
CGRect infoFrame = self.myInfoWindowView.frame;
infoFrame.origin.x = round(pontoNaMapView.x - CGRectGetWidth(infoFrame)/2);
infoFrame.origin.y = round(pontoNaMapView.y - markerSelecionado.icon.size.height - CGRectGetHeight(infoFrame));
self.myInfoWindowView.frame = infoFrame; // H
}
O primeiro passo é adicionar sua UIView como uma subview escondida do mapa (A).
Quando o usuário tocar no marcador, você deve exibir a UIView (B), posicionar a câmera sobre o marcado (C), calcular a posição da UIView sobre o marcador (D e H) e avisar ao mapa que ele não deve executar o procedimento padrão de toque (E).
Se o usuário tocar em outra área do mapa fora do marcador e da UIView, você deve esconder a UIView (F).
Se o usuário arrastar, der zoom ou executar qualquer outra ação que modifique a câmera, você deve reposicionar a UIView de acordo (G).
Executando os passos acima, você pode criar sua própria InfoWindow com botões e animações que quiser como no exemplo abaixo.
Até a próxima, com recursos mais avançados do SDK.