自定义信息窗口上的按钮未在ios中接收操作

时间:2014-04-21 12:47:41

标签: ios objective-c cocoa-touch google-maps google-maps-sdk-ios

我在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方法无法触发。

7 个答案:

答案 0 :(得分:5)

我还没有使用谷歌地图SDK,但在看了几个链接后,你似乎想要完成的事情似乎并不容易。

参考:https://developers.google.com/maps/documentation/android/infowindows
PS:这可能是Android文档,但它似乎也适用于iOS。

引用:

  

注意:绘制的信息窗口不是实时视图。观点是   在它的时候呈现为图像(使用View.draw(Canvas))   回。这意味着对视图的任何后续更改都不会   通过地图上的信息窗口反映出来。更新信息窗口   稍后(例如,在图片加载后),请致电showInfoWindow()。   此外,信息窗口不会考虑任何交互性   典型的普通视图,如触摸或手势事件。不管你   可以在整个信息窗口上收听通用点击事件   在下面的部分中描述。

您可以改为实施GMSMapViewDelegate's -didTapInfoWindowOfMarker:委托方法来检查信息窗是否被点击 (缺点是整个infowindow变成一个按钮


其他链接:

similar question 1
similar question 2

答案 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)

  1. 使用按钮创建一个子视图。
  2. 将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()
        }

I have added customInfoWindow like this

并将此视图(customInfoWindow)的出口放在具有mapView的同一控制器中。

感谢这位开发人员Custom and interactive googlemaps(IOS SDK) infowindow

,我从这个链接中得到了这个想法