google maps sdk ios - route - Ventana de información personalizada para Google Maps
ios google map sdk draw route (4)
Para aquellos que intentan agregar botones a una vista personalizada que representa la ventana de información, parece ser imposible de hacer, porque el SDK de Google Maps lo dibuja como una imagen o algo como esto. Pero hay una solución bastante simple:
- Tienes que crear una vista personalizada con botones y lo que necesites que se muestre en tu ventana de información.
- Agréguelo como una subvista en su método mapView (mapView: GMSMapView, didTapMarker marker: GMSMarker) . Puede establecer una posición de una vista personalizada obteniendo las coordenadas de un marcador tocado con la ayuda de mapView.projection.pointForCoordinate (marker.position)
Es posible que su vista personalizada tenga que cambiar su posición siguiendo la posición de la cámara, por lo que debe manejar mapView (mapView: GMSMapView, didChangeCameraPosition position: GMSCameraPosition) donde puede actualizar fácilmente su posición de vista personalizada.
var infoWindow = CustomInfoView() var activePoint : POIItem? func mapView(mapView: GMSMapView, didTapMarker marker: GMSMarker) -> Bool { if let poiItem = marker as? POIItem { // Remove previously opened window if any if activePoint != nil { infoWindow.removeFromSuperview() activePoint = nil } // Load custom view from nib or create it manually // loadFromNib here is a custom extension of CustomInfoView infoWindow = CustomInfoView.loadFromNib() // Button is here infoWindow.testButton.addTarget(self, action: #selector(self.testButtonPressed), forControlEvents: .AllTouchEvents) infoWindow.center = mapView.projection.pointForCoordinate(poiItem.position) activePoint = poiItem self.view.addSubview(infoWindow) } return false } func mapView(mapView: GMSMapView, didChangeCameraPosition position: GMSCameraPosition) { if let tempPoint = activePoint { infoWindow.center = mapView.projection.pointForCoordinate(tempPoint.position) } }
Me gustaría crear una ventana de información personalizada para Google Maps para iOS, como la foto a continuación. ¿Es posible extender GMSOverlay como GMSMarker, GMSPolyline y GMSPolygon do para crear gráficos personalizados?
Puedes pasar este tipo de UIImage como un icono como debajo
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(latitude,longitude);
GMSMarker *location = [GMSMarker markerWithPosition:position];
location.title = @"Location Name";
location.icon = [UIImage imageNamed:@"marker_icon.png"];
location.map = mapView_;
Para más detalles vea esta Documentación .
Si desea este tipo de imagen después de presionar un marcador, debe tener dos tipos de imágenes de un solo lugar.
1er icono de marcador de imagen solamente.
La segunda imagen es marcador con detalle de lugar.
icono marcador cargado cuando mapView inicializa como el código anterior.
Y el marcador de Segunda Imagen con el detalle de lugar que tiene que cargar como este dentro del método de delegate
presionado marcador utilizando For-Loop
y NSMutablearray
marcando marker.title
para saber qué marcador se presiona.
- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker
{
}
Versión Swift, versión de ejemplo de la clase personalizada de marcador:
class CustomMarker: UIView {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var seperator: UIImageView!
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var descriptionLabel: UILabel!
class func instanceFromNib() -> UIView {
return UINib(nibName: "CustomMarker", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
}}
Gracias a Cómo inicializar una Clase UIView con un archivo xib en Swift, iOS puedes agregar extensiones a UIView para que no necesites el lanzamiento
protocol UIViewLoading {}
extension UIView : UIViewLoading {}
extension UIViewLoading where Self : UIView {
// note that this method returns an instance of type `Self`, rather than UIView
static func loadFromNib() -> Self {
let nibName = "/(self)".characters.split{$0 == "."}.map(String.init).last!
let nib = UINib(nibName: nibName, bundle: nil)
return nib.instantiateWithOwner(self, options: nil).first as! Self
}
}
Y en tu delegado:
func mapView(mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
let customMarker:CustomMarker = CustomMarker.loadFromNib()
customMarker.titleLabel.text = marker.title
customMarker.descriptionLabel.text = marker.snippet
return customMarker
}
markerInfoWindow
utilizar el método de delegado markerInfoWindow
junto con la configuración de infoWindowAnchor
.
Cuando creas tu marcador, establece el anclaje:
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = MARKER_POSITION;
marker.infoWindowAnchor = CGPointMake(0.44f, 0.45f);
marker.icon = [UIImage imageNamed:@"CustomMarkerImageName"];
luego crea el método de delegado:
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
InfoWindow *view = [[[NSBundle mainBundle] loadNibNamed:@"InfoWindow" owner:self options:nil] objectAtIndex:0];
view.name.text = @"Place Name";
view.description.text = @"Place description";
view.phone.text = @"123 456 789";
view.placeImage.image = [UIImage imageNamed:@"customPlaceImage"];
view.placeImage.transform = CGAffineTransformMakeRotation(-.08);
return view;
}
En el ejemplo anterior, creé un xib y cargué ese xib, devolviendo el UIView
resultante. En su lugar, podría construir una UIView
utilizando solo código.