Пользовательское информационное окно для карт Google
Я хотел бы сделать пользовательское информационное окно для Google Maps для iOS, как на фотографии ниже. Можно ли расширить GMSOverlay, как GMSMarker, GMSPolyline и GMSPolygon, чтобы создать пользовательскую графику?
4 ответа:
для тех, кто пытается добавить кнопки в пользовательский вид, представляющий информационное окно - это кажется невозможным, потому что Google Maps SDK рисует его как изображение или что-то вроде этого. Но есть и довольно простое решение:
- вы должны создать пользовательский вид с кнопками и все, что вам нужно будет отображаться в окне Информация.
- добавить его в качестве подпанели в mapView (mapView: GMSMapView, didtapmarker маркер: GMSMarker) метод. Вы можно установить положение пользовательского вида, получив координаты маркера постучал с помощью mapView.проекция.pointForCoordinate (маркер.позиция)
ваш пользовательский вид, возможно, должен изменить его положение, следуя положению камеры, поэтому вам нужно обрабатывать mapView(mapView: GMSMapView, didchangecameraposition позиция: GMSCameraPosition) где вы можете легко обновить свою пользовательскую позицию просмотра.
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) } }
вы хотите использовать
markerInfoWindow
делегировать метод вместе с установкойinfoWindowAnchor
.при создании маркера установите якорь:
GMSMarker *marker = [[GMSMarker alloc] init]; marker.position = MARKER_POSITION; marker.infoWindowAnchor = CGPointMake(0.44f, 0.45f); marker.icon = [UIImage imageNamed:@"CustomMarkerImageName"];
затем создайте метод делегата:
- (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; }
в примере выше, я создал xib и я загрузил этот xib, возвращая полученный
UIView
. Вместо этого вы можете построитьUIView
используя только код.
вы можете передать этот тип UIImage как значок, как показано ниже
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(latitude,longitude); GMSMarker *location = [GMSMarker markerWithPosition:position]; location.title = @"Location Name"; location.icon = [UIImage imageNamed:@"marker_icon.png"]; location.map = mapView_;
для более подробной информации смотрите эту документацию.
если вы хотите, чтобы этот тип изображения после нажатия маркера, чем вы должны иметь два типа изображений одного места.
1-й значок маркера изображения только.
2-е изображение-это маркер с детализацией места.
значок маркера загружается, когда mapView инициализировать, как выше код.
и второй маркер изображения с поместите деталь, которую вы должны загрузить, как это внутри маркера нажата
delegate
способ использованияFor-Loop
иNSMutablearray
проверкаmarker.title
чтобы узнать, какой маркер нажат.- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { }
Swift версия, пример версии маркера пользовательского класса:
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 }}
спасибо как инициализировать класс UIView с файлом xib в Swift, iOS вы можете добавить расширение в UIView, так что вам не нужно cast
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{ == "."}.map(String.init).last! let nib = UINib(nibName: nibName, bundle: nil) return nib.instantiateWithOwner(self, options: nil).first as! Self } }
и в вашем делегате:
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 }