如何在 ios 上向谷歌地图标记信息窗口添加按钮?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15537206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can i add a button to google maps marker info window on ios?
提问by user1810991
I have added Google maps sdk for ios to my Iphone app, and i have some custom markers if clicked info window pops up with title, how can i add a button to this info window so if pressed will go to new page? Now i have tryed to use this post to solve this issue Adding Click Event on InfoWindow/Marker in Google Maps SDK for native iOS/objective Cit doesnt give me error but it won't work.
我已将适用于 ios 的谷歌地图 sdk 添加到我的 Iphone 应用程序,如果单击的信息窗口弹出带有标题,我有一些自定义标记,我如何向此信息窗口添加按钮,以便如果按下将转到新页面?现在我已经尝试使用这篇文章来解决这个问题在 Google Maps SDK 的 InfoWindow/Marker 上添加 Click Event for native iOS/objective C它不会给我错误,但它不会工作。
this is what i want my result to be:http://www.flickr.com/photos/74719051@N05/6728157477/
这就是我想要的结果:http: //www.flickr.com/photos/74719051@N05/6728157477/
回答by Saxon Druce
The answer for the question you linked shows code for using MapKit, so it wouldn't work with the Google Maps SDK for iOS.
您链接的问题的答案显示了使用 MapKit 的代码,因此它不适用于 iOS 版 Google Maps SDK。
See this question for how to return a custom view with the Google Maps SDK for iOS:
请参阅此问题以了解如何使用适用于 iOS 的 Google Maps SDK 返回自定义视图:
Custom annotation view in Google Maps SDK
However note that according to this question, it looks like what is displayed might be a visual copy of the view not the actual view, which might limit the interaction you can do with the view:
但是请注意,根据这个问题,看起来显示的内容可能是视图的视觉副本,而不是实际视图,这可能会限制您可以与视图进行的交互:
Add buttons to view returned by markerInfoWindow delegate method
添加按钮以查看由markerInfoWindow 委托方法返回的视图
Simply detecting a tap on the info window and going to a different page should be possible using didTapWindowOfMarker
though.
didTapWindowOfMarker
尽管如此,只需检测信息窗口上的点击并转到不同的页面应该是可能的。
Note that there's a feature request in Google's issue tracker to add direct support for this:
请注意,Google 的问题跟踪器中有一个功能请求,可以添加对此的直接支持:
https://code.google.com/p/gmaps-api-issues/issues/detail?id=4961
https://code.google.com/p/gmaps-api-issues/issues/detail?id=4961
回答by Aurelien Porte
This code does exactly what you want. It's inspired by #9 in the linkrecommended by Saxon Druce but done differently and more complete. It detects tap on buttons added to my custom infoWindow. I create a custom infoWindow with 2 fake buttons (they could actually be replaced by images because they won't trigger any action anyway) and I add a transparent UIView with 2 real but transparent buttons over the infoWindow. These buttons will trigger the actions.
此代码完全符合您的要求。它的灵感来自Saxon Druce 推荐的链接中的 #9,但做得不同且更完整。它检测添加到我的自定义 infoWindow 的按钮的点击。我创建了一个带有 2 个假按钮的自定义信息窗口(它们实际上可以被图像替换,因为它们无论如何都不会触发任何操作)并且我在信息窗口上添加了一个带有 2 个真实但透明的按钮的透明 UIView。这些按钮将触发操作。
Finally, I use a few delegate methods or KVC in order to move the overlaid UIView when the infoWindow itself moves.
最后,我使用了一些委托方法或 KVC,以便在 infoWindow 本身移动时移动覆盖的 UIView。
- (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;
}
回答by Sourabh Sharma
Swift 3.0 solutionfor button handling on CustomInfoWindow
CustomInfoWindow 上按钮处理的Swift 3.0 解决方案
https://stackoverflow.com/a/40681031/3933302
https://stackoverflow.com/a/40681031/3933302
More more detail visit this blog
更多详情请访问此博客
回答by Dhananjay Patil
1)Create one subview which you want to show in infoWindow. 2)Set frame of subview equals to frame of infoWindow view.
1) 创建一个要在 infoWindow 中显示的子视图。2)设置子视图的框架等于信息窗口视图的框架。
subView = [[[NSBundle mainBundle] loadNibNamed:@"viewName" owner:self options:nil] objectAtIndex:0];
[subView setFrame:infoview.frame];
[self.mapview addSubview:subView];