Я хотел бы создать пользовательское информационное окно для Карт Google для iOS, как на фотографии ниже. Можно ли расширить GMSOverlay, например GMSMarker, GMSPolyline и GMSPolygon, для создания пользовательской графики?
Я хотел бы создать пользовательское информационное окно для Карт Google для iOS, как на фотографии ниже. Можно ли расширить GMSOverlay, например GMSMarker, GMSPolyline и GMSPolygon, для создания пользовательской графики?
Для тех, кто пытается добавить кнопки к пользовательскому представлению, представляющему информационное окно, это кажется невозможным, потому что SDK Google Maps рисует его как изображение или что-то в этом роде. Но есть довольно простое решение:
Возможно, вам нужно изменить свое положение, следуя позиции камеры, поэтому вам нужно обработать mapView (mapView: GMSMapView, didChangeCameraPosition position: 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_;
Подробнее см. эту документацию.
Если вы хотите, чтобы этот тип изображения был нажат после нажатия маркера, вы должны иметь два типа изображений одного места.
Только значок маркера изображения.
Второе изображение - маркер с деталями места.
Значок маркеразагружается, когда 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, чтобы вам не нужно было лить
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
}
}
И в вашем делегате:
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
}