Добавить кнопки для просмотра, возвращенные методом делегирования markerInfoWindow
В настоящее время я создаю и возвращаю пользовательский вид с SDK google maps ios, установив делегат на себя и используя следующий код.
#pragma mark - GMSMapViewDelegate
-(UIView*)mapView:(GMSMapView *)mapView markerInfoWindow:(id<GMSMarker>)marker {
int popupWidth = 200;
int contentWidth = 180;
int contentPad = 10;
int popupHeight = 140;
int popupBottomPadding = 16;
int popupContentHeight = popupHeight - popupBottomPadding;
int buttonHeight = 30;
UIView *outerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, popupWidth, popupHeight)];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, popupWidth, popupContentHeight)];
[view setBackgroundColor:[UIColor whiteColor]];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPad, 0, contentWidth, 22)];
[titleLabel setFont:[UIFont systemFontOfSize:17.0]];
titleLabel.text = [marker title];
UILabel *descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPad, 24, contentWidth, 20)];
[descriptionLabel setFont:[UIFont systemFontOfSize:11.0]];
descriptionLabel.text = [marker snippet];
[view addSubview:titleLabel];
[view addSubview:descriptionLabel];
UIButton *directionButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
directionButton.frame = CGRectMake(contentPad, 45, contentWidth, buttonHeight);
[directionButton setTitle:@"Directions" forState:UIControlStateNormal];
[directionButton addTarget:self action:@selector(directionsPressed) forControlEvents:UIControlEventTouchDown];
UIButton *viewLocationButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[viewLocationButton addTarget:self action:@selector(viewLocationPressed) forControlEvents:UIControlEventTouchUpInside];
[viewLocationButton setTitle:@"View Location" forState:UIControlStateNormal];
viewLocationButton.frame = CGRectMake(contentPad, 80, contentWidth, buttonHeight);
// handle bottom dealio
UIImage *bottomImage = [UIImage imageNamed:@"map-pointer-bottom"];
UIImageView *bottomView = [[UIImageView alloc] initWithFrame:CGRectMake((popupWidth / 2) - (bottomImage.size.width / 2), (popupContentHeight), bottomImage.size.width, bottomImage.size.height)];
[bottomView setImage:bottomImage];
[outerView addSubview:view];
[outerView addSubview:bottomView];
[outerView addSubview:directionButton];
[outerView addSubview:viewLocationButton];
ListItem *li = (ListItem*)[marker userData];
self.currentItem = li;
NSLog(@"List Item %@ - %@", li.type, li.typeid);
return outerView;
}
-(void)directionsPressed {
NSLog(@"Directions Pressed");
}
-(void)viewLocationPressed {
NSLog(@"Location View Pressed");
}
- (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(id<GMSMarker>)marker {
NSLog(@"Tap Captured");
}
Делается didTapWindowOfMarker, когда я нажимаю пользовательский вид, но ни один из целевых методов для кнопок не запускается.
Любые идеи, почему это может быть?
Ответы
Ответ 1
Возможно, как уже упоминалось официально в документации API Google Maps для Android, нижеследующее ограничение в отношении infowindows относится также к SDK Google Maps iOS:
Информационное окно не представляет собой живой вид, а представление отображается как изображение на карте. В результате, любые слушатели, которые вы установили в представлении, не учитываются, и вы не можете различать события кликов в разных частях представления. Вам не рекомендуется размещать интерактивные компоненты, такие как кнопки, флажки или текстовые входы, в вашем пользовательском информационном окне.
Таким образом, в основном нажатие на любую часть инфо-окна приведет только к " didTapWindowOfMarker"
Ответ 2
Решение Swift 3.0
//empty the default infowindow
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
return UIView()
}
// reset custom infowindow whenever marker is tapped
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
customInfoView.removeFromSuperview()
// customInfoView.button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
self.view.addSubview(customInfoView)
// Remember to return false
// so marker event is still handled by delegate
return false
}
// let the custom infowindow follows the camera
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
if (locationMarker != nil){
let location = locationMarker.position
customInfoView.center = mapView.projection.point(for: location)
}
}
// take care of the close event
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
customInfoView.removeFromSuperview()
}
![Я добавил customInfoWindow, как это]()
и сделать выход этого представления (customInfoWindow) в том же контроллере, который имеет mapView.
У меня появилась идея из этой ссылки благодаря этому разработчику Конфигурация пользовательских и интерактивных googlemaps (IOS SDK)
Ответ 3
У меня есть UView, и я добавляю делегата в представление, чтобы UIButton вызывал селектор. Для google-карты я ничего не делаю, когда звоню
- (void) mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker;
Тем не менее, я устанавливаю свой делегат (мой пользовательский вид) для себя и вызываю все свои действия, когда я нажимаю кнопку, связанную с селектором.
Ответ 4
UPDATE:
Вот код, который я использую для обнаружения нажатия кнопок, добавленных в мои информационные окна. Я создаю customWindow с двумя поддельными кнопками (они могут быть фактически заменены изображениями, потому что они не будут запускать какое-либо действие), и я добавляю полностью прозрачный оверлей с двумя реальными кнопками над информационным окном. Эти кнопки активируют действия.
И я использую несколько методов делегата или KVC, чтобы переместить оверлей при перемещении самого информационного окна.
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
[self.actionOverlayCalloutView removeFromSuperview];
UIView *calloutView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, infoWindowWidth, infoWindowHeight)];
float offset = anchorSize * M_SQRT2;
CGAffineTransform rotateBy45Degrees = CGAffineTransformMakeRotation(M_PI_4);
UIView *arrow = [[UIView alloc] initWithFrame:CGRectMake((infoWindowWidth - anchorSize)/2.0, infoWindowHeight - offset, anchorSize, anchorSize)];
arrow.transform = rotateBy45Degrees;
arrow.backgroundColor = [UIColor lightGrayColor];
[calloutView addSubview:arrow];
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, infoWindowWidth, infoWindowHeight - offset/2)];
[contentView setBackgroundColor:[UIColor whiteColor]];
contentView.layer.cornerRadius = 5;
contentView.layer.masksToBounds = YES;
contentView.layer.borderColor = [UIColor lightGrayColor].CGColor;
contentView.layer.borderWidth = 1.0f;
self.actionOverlayCalloutView =
[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:contentView]]; //hack to copy a view...
self.actionOverlayCalloutView.backgroundColor = [UIColor lightGrayColorWithAlpha:0.5];
self.actionOverlayCalloutView.layer.cornerRadius = 5;
NSMutableArray *falseButtons = [NSMutableArray array];
NSMutableArray *actionButtons = [NSMutableArray array];
PointMapItem *pointAnnotation = marker.userData;
if ([pointAnnotation canPerformSend]) {
UIButton *button = [[UIButton alloc] init];
[button setImage:[UIImage imageNamed:@"imageButton1.png"] forState:UIControlStateNormal];
[falseButtons addObject:button];
UIButton *activableButton = [[UIButton alloc] init];
[activableButton addTarget:self action:@selector(onButton1Clicked) forControlEvents:UIControlEventTouchUpInside];
[actionButtons addObject:activableButton];
}
if ([pointAnnotation canPerformShowDetails]) {
UIButton *button = [[UIButton alloc] init];
[button setImage:[UIImage imageNamed:@"imageButton1.png"] forState:UIControlStateNormal];
[falseButtons addObject:button];
UIButton *activableButton = [[UIButton alloc] init];
[activableButton addTarget:self action:@selector(onButton2Clicked) forControlEvents:UIControlEventTouchUpInside];
[actionButtons addObject:activableButton];
}
int buttonWidth = contentView.frame.size.width / [falseButtons count];
int currentOffset = 0;
for (int i=0; i<falseButtons.count; i++) {
UIButton *falseButton = [falseButtons objectAtIndex:i];
UIButton *activableButton = [actionButtons objectAtIndex:i];
[falseButton setFrame:CGRectMake(currentOffset, 0, buttonWidth, contentView.frame.size.height)];
currentOffset += buttonWidth;
activableButton.frame = falseButton.frame;
[activableButton setTitle:@"" forState:UIControlStateNormal];
[self.actionOverlayCalloutView addSubview:activableButton];
[contentView addSubview:falseButton];
}
[calloutView addSubview:contentView];
CLLocationCoordinate2D anchor = [self.mapView.selectedMarker position];
CGPoint point = [self.mapView.projection pointForCoordinate:anchor];
point.y -= self.mapView.selectedMarker.icon.size.height + offset/2 + (infoWindowHeight - offset/2)/2;
self.actionOverlayCalloutView.center = point;
[self.mapView addSubview:self.actionOverlayCalloutView];
return calloutView;
}
- (void)mapView:(GMSMapView *)pMapView didChangeCameraPosition:(GMSCameraPosition *)position {
if (pMapView.selectedMarker != nil && self.actionOverlayCalloutView.superview) {
CLLocationCoordinate2D anchor = [self.mapView.selectedMarker position];
CGPoint point = [self.mapView.projection pointForCoordinate:anchor];
float offset = anchorSize * M_SQRT2;
point.y -= self.mapView.selectedMarker.icon.size.height + offset/2 + (infoWindowHeight - offset/2)/2;
self.actionOverlayCalloutView.center = point;
} else {
[self.actionOverlayCalloutView removeFromSuperview];
}
}
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
[self.actionOverlayCalloutView removeFromSuperview];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"mapView.selectedMarker"]) {
if (!self.mapView.selectedMarker) {
[self.actionOverlayCalloutView removeFromSuperview];
}
}
}
- (void)onButton2Clicked {
//your code
self.mapView.selectedMarker = nil;
}
- (void)onButton1Clicked {
// your code;
self.mapView.selectedMarker = nil;
}
БЫВШАЯ ПОЧТА:
Взгляните на эту тему, а именно на # 9, должно быть полезно
https://code.google.com/p/gmaps-api-issues/issues/detail?id=4961
Ответ 5
1) Создайте одно подзаголовок, которое вы хотите показать в окне infoWindow.
2) Установите фрейм подкадров равным кадру вида infoWindow.
[subView setFrame:infoview.frame];
subView = [[[NSBundle mainBundle] loadNibNamed:@"viewName" owner:self options:nil] objectAtIndex:0];
[self.mapview addSubview:subView];