iOS GMaps delegate mapView: markerInfoWindow: not implemented - ios

I am trying to create custom Info Window for marker. I am using Google Maps SDK for iOS.
I have created custom XIB file with all objects. Created class for it.
Called GMSMapViewDelegate in Header file
in implementation file I implemented following method:
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker {
NSLog(#"Implementing delegate Method");
CustomInfoWindow *infoWindow = [[[NSBundle mainBundle]
loadNibNamed:#"InfoWindow"
owner:self
options:nil]
objectAtIndex:0];
infoWindow.title.text = #"This is title";
infoWindow.address.text = #"This is address";
infoWindow.status.text = #"Here will be status";
return infoWindow;
}
But there is still default marker. What could be the issue?
Thanks for help.

Try if not add GMSMapView Delegate
You add GMSMapView Delegate in in implementation file
GMSMapView * mapView_ = [GMSMapView mapWithFrame:viewmapbaseView.bounds camera:camera];
mapView_.delegate=self;

Related

GMSMarker custom infoWindow doesn't shown

I've implemented -mapView: markerInfoWindow: on my application and until now everything was working perfectly, but yesterday I've updated the Google Maps iOS SDK to the latest version (1.12.23211.0) and since then the info window doesn't being shown and the default info window (white bar with a title) is displayed instead.
I tried to reinstall the last version of the SDK (using Cocoa pods) but it's still not working (my custom info window isn't being shown).
Can anyone help me to solve this problem?
My code:
myVC:
-(UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker
{
//Creating "infoWindow"(infoWindow) and setting it with nib file called "infoWindow"
infoWindow *infoWindow=[[[NSBundle mainBundle] loadNibNamed:#"infoWindow" owner:self options:nil] firstObject];
//Setting "infoWindow"(infoWindow)'s storeNameLabel's text to "marker"(customMarker)'s title
infoWindow.storeNameLabel.text=((customMarker*)marker).title;
//Creating "fullAddress"(NSString) ands setting it to "marker"(customMarker)'s address
NSString *fullAddress = ((customMarker*)marker).address;
//Creating "addressArray"(NSArray) and adding it "address" without the city name (until the "," char)
NSArray *addressArray = [fullAddress componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]];
//Setting "infoWindow"(infoWindow)'s storeAddressLabel's text to "addressArray"(NSArray) first object
infoWindow.storeAddressLabel.text=[addressArray firstObject];
//Returning "infoWindow"(infoWindow)
return infoWindow;
}
-(void)createMarkerWithStore:(Store*)store
{
dispatch_async(dispatch_get_main_queue(), ^{
customMarker *marker=[[customMarker alloc] initWithPosition:store.geoPoint andTitle:store.storeName andAddress:store.address andIcon:store.category.markerIcon];
marker.map=self.mapView;
store.marker=marker;
});
}
customMarker:
-(void)awakeFromNib
{
self.storeNameLabel.adjustsFontSizeToFitWidth=YES;
self.storeAddressLabel.adjustsFontSizeToFitWidth=YES;
}
customMarker:
-(instancetype)initWithPosition:(CLLocationCoordinate2D)position andTitle:(NSString*)title andAddress:(NSString*)address andIcon:(UIImage*)icon
{
self=[super init];
if (self) {
self.position=position;
self.title=title;
self.address=address;
self.icon=icon;
self.flat=YES;
self.appearAnimation=kGMSMarkerAnimationPop;
}
return self;
}
Thank you very much!
The problem was that I forgot to set the delegate to the map

Can't receive touch events from markerInfoWindow UIView in GMSMapView

I have created a custom UIView with XIB and I display this when a user taps on a marker by implementing markerInfoWindow
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker
{
TESTInfoWindow *view = [[[NSBundle mainBundle] loadNibNamed:#"TESTInfoWindow" owner:self options:nil] objectAtIndex:0];
view.lblTitle.text = [marker title];
return view;
}
Everything works fine, my XIB is displayed and the title populated.
My issue is that I can't get the custom UIView, TESTInfoWindow to respond to touch events. (I want the user to be able to drag the custom info window and the app will respond based on the touchesEnd event.)
I've implemented touchesBegan and touchesMoved in TESTInfoWindow and neither get called:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"DEBUG touchesBegan");
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"DEBUG touchesMoved");
}
I think the GMSMapView is receiving the touches that are ignored by the custom info window view.
How do I get my custom UIView to receive the touches? Any help appreciated.
I just copied the answer for you from this link Adding Click Event on InfoWindow/Marker in Google Maps SDK for native iOS/objective C
1.conform to the GMSMapViewDelegate protocol.
#interface YourViewController () <GMSMapViewDelegate>
// your properties
#end
2.set your mapView_ delegate.
mapView_.delegate = self;
3.implement the GMSMapViewDelegate method
- (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker {
// your code
NSNumber *number = [marker.userData objectForKey:#"marker_id"];
}
btw, marker.userData is useful. you can set your needed data into it and use it in - mapView:didTapInfoWindowOfMarker:
Eg for set userData on GMSMarker object
GMSMarker *marker = [[GMSMarker alloc] init];
marker.userData = #{#"marker_id":[NSNumber numberWithInt:12]};

How to use custom callout for annotation when using Google maps in iOS?

I am using Google Maps in iOS app .So far I am able to show user location on the map. I am trying to use a custom callout when a annotation is clicked.
This is what I have done so far.
1] Created aXIB file and assigned a class name to it of a UIView subclass.
2] Used markerInfoWindow delegate method as below.
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker
{
CustomGoogleCallOut *view = [[[NSBundle mainBundle]loadNibNamed:#"CustomGoogleCallOut" owner:self options:nil]objectAtIndex:0];
view.callOutImageView.image = [UIImage imageNamed:#"avatar.png"];
view.callOutTitleLabel .text = #"title";
view.callOutUserName.text = #"Mario";
return view;
}
However I am not able to see call out.What am I missing here?
You are missing delegate. in h file
: UIViewController<GMSMapViewDelegate>
in .m file
mapView.delegate = self;

How to implement iOS Google Maps SDK

I just have a question and can't seem to find it anywhere.
I"m new to iOS development and trying to use Google Maps inside my application.
I went thru the example they give you here.
#import "DemoViewController.h"
#import <GoogleMaps/GoogleMaps.h>
#implementation DemoViewController {
GMSMapView *mapView_;
}
- (void)loadView {
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:1.285
longitude:103.848
zoom:12];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.view = mapView_;
}
#end
But as you can see the they set self.view = mapView_; and the UIView class doesn't have a view function.
I want the map to be inside a UIView I have that is inside another ViewController
Did I lose you yet? Either ways here is a picture.
So inside of the view (or whitespace) I want the map to load.
Thanks guys for the help.
So you've got a GMSMapView. And you can make one view a subview of another in the interface with addSubview:. I wouldn't do it in loadView if I were you, though. viewDidLoad is the earliest good opportunity.
I think your real problem is that you're way ahead of yourself. You're trying to do this without know how views work, how view controllers work, etc. I recommend you take a deep breath and learn about iOS programming before you jump in with all four feet. Otherwise you don't know what your code (or Google's code) even means.
I found a solution that works for me if anyone needs to do something similar.
I just used a container view and then made separate UIViewController class (that has the google maps sdk code add a map section) and then hooked it up to my main ViewController by using [self.view addSubview:googleMapsView]; googleMapsView being my container view that I connected to the main ViewController.
I did an exact same thing here.
Simply added a View of type GMSMapView via interface builder and then set up the properties in controller.
Please try below code.
#property (strong, nonatomic) IBOutlet GMSMapView *mapView;
-(void)addAllPinsOnMapView
{
arrMapPin=[[NSMutableArray alloc] init];
for(int i = 0; i < arrOfferList.count; i++)
{
GMSCameraPosition *cameraPosition=[GMSCameraPosition cameraWithLatitude:[[[arrOfferList objectAtIndex:i] objectForKey:#"latitude"] floatValue] longitude:[[[arrOfferList objectAtIndex:i] objectForKey:#"longitude"] floatValue] zoom:12];
// mapView = [GMSMapView mapWithFrame:CGRectZero camera:cameraPosition];
_mapView.camera = cameraPosition;
_mapView.myLocationEnabled=YES;
GMSMarker *marker=[[GMSMarker alloc]init];
marker.position=CLLocationCoordinate2DMake([[[arrOfferList objectAtIndex:i] objectForKey:#"latitude"] floatValue], [[[arrOfferList objectAtIndex:i] objectForKey:#"longitude"] floatValue]);
marker.title = [[arrOfferList objectAtIndex:i] objectForKey:#"business"];
marker.map=_mapView;
_mapView.delegate = self;
}
}
- (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:
(GMSMarker *)marker {
NSPredicate *result;
result=[NSPredicate predicateWithFormat:#"business CONTAINS[c] %#",marker.title];
NSArray * array = [arrOfferList filteredArrayUsingPredicate:result];
OfferDetailsViewController *objOfferDetailsViewController = [[OfferDetailsViewController alloc]init];
objOfferDetailsViewController.dictOfferDetails=[array objectAtIndex:0];
[self.navigationController pushViewController:objOfferDetailsViewController animated:YES];
}
- (IBAction)btnLocateMe:(UIButton *)sender
{
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:[[[AppDelegate initAppDelegate].DictLocation objectForKey:#"Latitude"] floatValue] longitude:[[[AppDelegate initAppDelegate].DictLocation objectForKey:#"Longitude"] floatValue] zoom:14];
[_mapView animateToCameraPosition:camera];
}

MKOverlays Combining Image Tiles And KML

I am trying to display tiled images with a kml overlay on top of the tiled images (code below) and am receiving the following error:
'NSInvalidArgumentException', reason: '-[MKPolyline tilesInMapRect:zoomScale:]: unrecognized selector sent to instance
Does anyone have any suggestions as to whether or not I am approaching the multiple overlays correctly or why I am getting this error?
Thanks in advance!
(void)viewDidLoad
{
[super viewDidLoad];
// Initialize the map overlay with tiles in the app's bundle.
NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Tiles"];
MapOverlay *overlay1 = [[MapOverlay alloc] initWithDirectory:tileDirectory];
// Locate the path to the route.kml file in the application's bundle
// and parse it with the KMLParser.
NSString *path = [[NSBundle mainBundle] pathForResource:#"route" ofType:#"kml"];
NSURL *url = [NSURL fileURLWithPath:path];
kmlParser = [[KMLParser alloc] initWithURL:url];
[kmlParser parseKML];
// Add all of the MKOverlay objects parsed from the KML file to the map.
NSArray *overlay2 = [kmlParser overlays];
[map addOverlay:overlay1];
[map addOverlays:overlay2];
// Set the starting location.
CLLocationCoordinate2D startingLocation;
startingLocation.latitude = 0.00;
startingLocation.longitude =-0.00;
map.region = MKCoordinateRegionMakeWithDistance(startingLocation, 4600, 4600);
[map setCenterCoordinate:startingLocation];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay1
{
MapOverlayView *view = [[MapOverlayView alloc] initWithOverlay:overlay1];
view.overlayAlpha = 1.0;
return view;
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay2:(id <MKOverlay>)overlay2
{
return [kmlParser viewForOverlay:overlay2];
}
#end
At least the viewForOverlay delegate method is not implemented correctly.
You've written two methods: mapView:viewForOverlay: and mapView:viewForOverlay2:.
But the map view will only always call mapView:viewForOverlay: since that is the method name defined by the MKMapViewDelegate protocol.
The mapView:viewForOverlay2: method will be ignored and not called by the map view.
So what happens is that when the overlay2 overlay array is added to the map, it calls the mapView:viewForOverlay: method which creates a MapOverlayView for the overlay (instead of getting the overlay view from kmlParser). This may cause issues (maybe MapOverlayView only handles MapOverlay-type overlays).
All overlays should be handled in the mapView:viewForOverlay: method.
To handle multiple types of overlays, check the overlay class and handle accordingly:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MapOverlay class]])
{
MapOverlayView *view = [[MapOverlayView alloc] initWithOverlay:overlay];
view.overlayAlpha = 1.0;
return view;
}
//if not a MapOverlay, get from kmlParser...
return [kmlParser viewForOverlay:overlay];
}
Remove the mapView:viewForOverlay2: method.

Resources