我在iOS应用程序中使用谷歌地图,并实现了一个自定义信息窗口,用于显示标记的标题 现在,我在该自定义信息窗口上添加了一个按钮,但我的问题是没有调用按钮操作方法。
CustomInfoWindow.h
#import <UIKit/UIKit.h>
@interface CustomInfoWindow : UIView
@property (nonatomic,weak) IBOutlet UILabel *addressLabel;
@property(nonatomic) IBOutlet UIButton *button;
@end
并在infoWindow.xib
中添加了
UILabel
名为addressLabel
UIButton
名为button
ViewController.h
#import "CustomInfoWindow.h"
@interface viewController : UIViewController<GMSMapViewDelegate>
{
GMSMapView *mapView;
}
@end
ViewController.m
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker
{
NSLog(@"Mrker Tapped");
CustomInfoWindow *infoWindow = [[[NSBundle mainBundle]loadNibNamed:@"infoWindow"
owner:self
options:nil] objectAtIndex:0];
infoWindow.addressLabel.text = marker.title;
[infoWindow.button addTarget:self action:@selector(ButtonPressed)
forControlEvents:UIControlEventTouchUpInside];
return infoWindow;
}
-(void)ButtonPressed
{
NSLog(@"Button Pressed");
}
基本上...... ButtonPressed
方法无法触发。
答案 0 :(得分:5)
我还没有使用谷歌地图SDK,但在看了几个链接后,你似乎想要完成的事情似乎并不容易。
参考:https://developers.google.com/maps/documentation/android/infowindows
PS:这可能是Android文档,但它似乎也适用于iOS。
引用:
注意:绘制的信息窗口不是实时视图。观点是 在它的时候呈现为图像(使用
View.draw(Canvas)
) 回。这意味着对视图的任何后续更改都不会 通过地图上的信息窗口反映出来。更新信息窗口 稍后(例如,在图片加载后),请致电showInfoWindow()
。 此外,信息窗口不会考虑任何交互性 典型的普通视图,如触摸或手势事件。不管你 可以在整个信息窗口上收听通用点击事件 在下面的部分中描述。
您可以改为实施GMSMapViewDelegate's -didTapInfoWindowOfMarker:
委托方法来检查信息窗是否被点击
(缺点是整个infowindow变成一个按钮)
其他链接:
答案 1 :(得分:0)
看看你的这段代码 -
[infoWindow.button addTarget:self action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside];
在这里我猜你的按钮名称应该以大写字母&#34; B&#34;如: -
[infoWindow.Button addTarget:self action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside];
因为你有@property(非原子)IBOutlet UIButton * Button;
答案 2 :(得分:0)
首先在.h头文件中写下CustomInfoWindow *infoWindow
它的属性。
然后在.m类文件中合成,然后尝试添加目标
答案 3 :(得分:0)
我认为infoWindow太小了,而且它上面的按钮放在它外面。
尝试检查infoWindow的框架。您还可以将任何背景颜色应用于infoWindow。或者做infoWindow.clipToBounds=YES
。如果按钮被放置在视图的旁边,那么它会被修剪掉。
更改此
[infoWindow.button addTarget:self action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside];
到
[infoWindow.button addTarget:infoWindow action:@selector(ButtonPressed) forControlEvents:UIControlEventTouchUpInside];
在ButtonPressed
课程中声明CustomInfoWindow
。
答案 4 :(得分:0)
您无法在infoWindow中添加按钮。
为此,您必须创建自己的自定义信息窗口,并在其中添加按钮。
map_ViewController.h
#import <UIKit/UIKit.h>
#import <GoogleMaps/GoogleMaps.h>
#import "CustomInfoWindow.h"
@interface Map_ViewController : UIViewController <GMSMapViewDelegate>{
BOOL canHideInfoWindow;
}
@property (strong, nonatomic) IBOutlet GMSMapView *map;
@property (strong, nonatomic) CustomInfoWindow *displayedInfoWindow;
@property BOOL markerTapped;
@property BOOL cameraMoving;
@property BOOL idleAfterMovement;
@property (strong, nonatomic) GMSMarker *currentlyTappedMarker;
@property (assign, nonatomic) CLLocationCoordinate2D position;
@end
Map_ViewController.m
#import "Map_ViewController.h"
@interface Map_ViewController ()
@end
@implementation Map_ViewController
#pragma mark - viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
//get user position, i wont put all the code, only the code necessary for this topic
self.position =CLLocationCoordinate2DMake(POSITION);
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:self.position.latitude longitude:self.position.longitude zoom:15 bearing:0 viewingAngle:60];
_map = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.view = _map;
[self createMarkers]
}
#pragma mark create markers
-(void)createMarkers{
//settings(controls) on map
_map.delegate = self;
self.edgesForExtendedLayout = UIRectEdgeNone;
_map.accessibilityElementsHidden = NO;
_map.settings.compassButton = YES;
_map.settings.myLocationButton = YES;
_map.myLocationEnabled = YES;
[_map setMinZoom:8 maxZoom:19 ];
//remove all markers before to create the new one
[_map clear];
//this code above will center all markers on the map
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init];
//creates pin markers
//for this code, i used an model to store all markers.. again, i wont write it here.. so create by yourself the loop for it
for (marker in markersArray){
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(LAtLongPosition);
marker.appearAnimation = kGMSMarkerAnimationPop;
marker.userData = marker;
marker.map = _map;
bounds = [bounds includingCoordinate:marker.position];
}
//include user location too
bounds = [bounds includingCoordinate:self.position];
//center the map
[_map animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:50]];
}
#pragma mark - GoogleMaps Delegate
// Since we want to display our custom info window when a marker is tapped, use this delegate method
- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker{
// A marker has been tapped, so set that state flag
self.markerTapped = YES;
// If a marker has previously been tapped and stored in currentlyTappedMarker, then nil it out
if(self.currentlyTappedMarker) {
self.currentlyTappedMarker = nil;
}
// make this marker our currently tapped marker
self.currentlyTappedMarker = marker;
// if our custom info window is already being displayed, remove it and nil the object out
if([self.displayedInfoWindow isDescendantOfView:self.view]) {
[self.displayedInfoWindow removeFromSuperview];
self.displayedInfoWindow = nil;
}
/* animate the camera to center on the currently tapped marker, which causes
mapView:didChangeCameraPosition: to be called */
GMSCameraUpdate *cameraUpdate = [GMSCameraUpdate setTarget:marker.position];
[_map animateWithCameraUpdate:cameraUpdate];
return YES;
}
- (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position{
cameraMoving state flag to YES
if(self.markerTapped) {
self.cameraMoving = YES;
}
//Move the custom info window with the map
CGPoint markerPoint = [_map.projection pointForCoordinate:self.currentlyTappedMarker.position];
CGRect frame = self.displayedInfoWindow.bounds;
frame.origin.y = markerPoint.y - self.displayedInfoWindow.frame.size.height - 15 ;
frame.origin.x = markerPoint.x - self.displayedInfoWindow.frame.size.width / 2;
self.displayedInfoWindow.frame = frame;
}
/* If the map is tapped on any non-marker coordinate, reset the currentlyTappedMarker and remove our
custom info window from self.view */
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate{
if(self.currentlyTappedMarker) {
self.currentlyTappedMarker = nil;
}
if([self.displayedInfoWindow isDescendantOfView:self.view]) {
[self.displayedInfoWindow removeFromSuperview];
self.displayedInfoWindow = nil;
}
}
#pragma mark create infoWindow
// This method gets called whenever the map was moving but has now stopped
- (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position{
/* if we got here and a marker was tapped and our animate method was called, then it means we're ready
to show our custom info window */
if(self.markerTapped && self.cameraMoving) {
infosMarker = self.currentlyTappedMarker.userData;
// reset our state first
self.cameraMoving = NO;
self.markerTapped = NO;
self.idleAfterMovement = YES;
//CREATE YOUR INFO WINDOW VIEW (CustomInfoWindow : UIView)and load it
self.displayedInfoWindow = [[[NSBundle mainBundle] loadNibNamed:@"CustomInfoWindow" owner:self options:nil] objectAtIndex:0];
CGPoint markerPoint = [_map.projection pointForCoordinate:self.currentlyTappedMarker.position];
CGRect frame = self.displayedInfoWindow.bounds;
frame.origin.y = markerPoint.y - self.displayedInfoWindow.frame.size.height - 15;
frame.origin.x = markerPoint.x - self.displayedInfoWindow.frame.size.width / 2;
self.displayedInfoWindow.frame = frame;
[self.displayedInfoWindow.YOURBUTTON addTarget:self action:@selector(YOURBUTTONFUNCTION:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.displayedInfoWindow];
}
}
-(void)YOURBUTTONFUNCTION:(UIButton *)sender{
NSLog(@"YOURBUTTONFUNCTION TAPPED");
}
@end
答案 5 :(得分:0)
将infoWindow视图的框架分配给子视图框架。
[subView setFrame:infoview.frame];
subView = [[[NSBundle mainBundle] loadNibNamed:<YourViewName> owner:self options:nil] objectAtIndex:0]; [self.mapview addSubview:subView];
答案 6 :(得分:0)
Swift 3.0解决方案
首先设置mapView(GMSMapViewDelegate)的委托
//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)的出口放在具有mapView的同一控制器中。
感谢这位开发人员Custom and interactive googlemaps(IOS SDK) infowindow
,我从这个链接中得到了这个想法