infowindow not displaying with marker in didTapAtCoordinate method - objective-c

i am trying to show infowindow and marker both simultaneously.
code
-(void)set_markerOnMap:(double)lat longitude:(double)lon{
GMSMarker *marker = [[GMSMarker alloc] init];
marker.title = #"Location selected";
marker.position = CLLocationCoordinate2DMake(lat, lon);
marker.snippet = #"Testing";
marker.icon=[UIImage imageNamed:#"red-pin.png"];
marker.map = self.MyMapView;
[self.MyMapView setSelectedMarker:marker];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self set_markerOnMap:21.214894 longitude:72.88087];
self.MyMapView.delegate=self;
}
above code is working fine and its showing both infowindow and marker together.
but my problem is when i called set_markerOnMap method from didTapAtCoordinate instead of viewDidLoad it does not work and only marker is shown.
code:
- (void)viewDidLoad
{
[super viewDidLoad];
self.MyMapView.delegate=self;
}
- (void) mapView: (GMSMapView *) mapView
didTapAtCoordinate: (CLLocationCoordinate2D) coordinate{
[self set_markerOnMap:21.214894 longitude:72.88087];
}
anyone can help me where i am wrong?

See if this works...
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self set_markerOnMap:21.214894 longitude:72.88087];
}];

So the short term answer, as hinted by i2Fluffy, is the following:
#implementation ViewController {
GMSMarker *tapMarker;
}
- (void)viewDidLoad {
[super viewDidLoad];
GMSMapView *mapView = (GMSMapView*)self.view;
mapView.delegate = self;
CLLocationCoordinate2D sydney = CLLocationCoordinate2DMake(-33.868, 151.2086);
mapView.camera = [GMSCameraPosition cameraWithTarget:sydney zoom:8];
tapMarker = [GMSMarker markerWithPosition:sydney];
tapMarker.title = #"Tap Marker";
tapMarker.map = (GMSMapView*)self.view;
}
-(void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {
NSLog(#"Tap at (%g,%g)", coordinate.latitude, coordinate.longitude);
tapMarker.position = coordinate;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[((GMSMapView*)self.view) setSelectedMarker:tapMarker];
}];
}
#end
The longer term answer is that this is a bug (gmaps-api-issues/7222) and I'll work with engineering to get this fixed.
Thanks for the report! =)

Related

Objective C - Have only one pin at a time?

I have 2 different set of pins on top of a map view. One pin appears first and it's the user location, then when you search for a location in the search bar multiple pins appear depending on the location. I want to have one pin showing at a time. Once you search for the location the user's location pin should disappear, and once you select one of the multiple pins you searched the others should disappear.
Here's my code:
#import "UbicacionVC.h"
#import "SWRevealViewController.h"
#import <MapKit/Mapkit.h>
#import "Location.h"
#interface UbicacionVC ()
#end
#implementation UbicacionVC
#synthesize mapView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self inicializarComponentes];
self.mapView.delegate = self;
self.searchBar.delegate = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)inicializarComponentes {
[self.btnContinuar.layer setCornerRadius:20.0f];
[self.btnCancelar.layer setCornerRadius:20.0f];
////
UITapGestureRecognizer *gestureMenu = [[UITapGestureRecognizer alloc] init];
[gestureMenu addTarget:self.revealViewController action:#selector(revealToggle:)];
[gestureMenu setCancelsTouchesInView:NO];
[self.btnLeftMenu addGestureRecognizer:gestureMenu];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
////
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[self->locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
NSLog(#"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
CLLocationDegrees lat = newLocation.coordinate.latitude;
CLLocationDegrees lon = newLocation.coordinate.longitude;
CLLocation * location = [[CLLocation alloc]initWithLatitude:lat longitude:lon];
self.viewRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 500, 500);
[self.mapView setRegion:self.viewRegion];
}
-(void)localSearch:(NSString*)searchString{
[self.mapView setRegion:self.viewRegion];
MKLocalSearchRequest * request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = [searchString lowercaseString];
request.region = self.viewRegion;
MKLocalSearch* search = [[MKLocalSearch alloc] initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
if([response.mapItems count] == 0){
NSLog(#"No matches \n");
}
else{
for(MKMapItem * item in response.mapItems){
Location * pin = [[Location alloc] initWith:item.placemark.title andSubtitle:item.phoneNumber andCoordinate:item.placemark.coordinate andImageName:#"" andURL:item.url.absoluteString];
[self.mapView addAnnotation:pin];
}
}
}];
}
#pragma mark UISearchBarDelegate
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
[searchBar resignFirstResponder];
[self.mapView removeAnnotations:[self.mapView annotations]];
[self localSearch:searchBar.text];
}
#pragma mark MKMapViewDelegate
-(MKAnnotationView*)mapView:(MKMapView*)sender viewForAnnotation: (id<MKAnnotation>)annotation{
static NSString* identifier = #"reusablePin";
MKAnnotationView * aView = [sender dequeueReusableAnnotationViewWithIdentifier:identifier];
if(!aView){
aView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
aView.canShowCallout = YES;
}
aView.annotation = annotation;
return aView;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"%#",view.annotation.title);
NSLog(#"%#",view.annotation.subtitle);
}
I want to have one pin showing at a time.
How about break; in for loop?
for(MKMapItem * item in response.mapItems){
Location * pin = [[Location alloc] initWith:item.placemark.title andSubtitle:item.phoneNumber andCoordinate:item.placemark.coordinate andImageName:#"" andURL:item.url.absoluteString];
[self.mapView addAnnotation:pin];
// one pin showed
break;
}
Once you search for the location the user's location pin should disappear,
and once you select one of the multiple pins you searched the others should disappear.
You can use didSelectAnnotationView method.
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
// once you select one of the multiple pins, the others should disappear.
for (MKPointAnnotation *annotation in mapView.annotations) {
if (view.annotation != annotation) {
[mapView removeAnnotation:annotation];
NSLog(#"yes!!");
}
}
}

iAds still refuse to work

Edit: Here's my AppDelegate as well (part of it)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
GameViewController *gameViewController = [[GameViewController alloc]init];
NSLog(#"NSLOG %#", [[gameViewController view]class]);
_bannerViewController = [[BannerViewController alloc]initWithContentViewController:gameViewController];
self.window.rootViewController = _bannerViewController;
[self.window makeKeyAndVisible];
return YES;
}
I am about to give up. I have tried 5 different ways just these past few days to get literally one single iAd to show correctly and as simple as Apple makes it seem, literally 100% of the time I either see no ad or get an error. I have followed the Apple documentation EXACTLY.
The only clue I have is in these two lines
GameViewController *gameViewController = [[GameViewController alloc]init];
NSLog(#"NSLOG %#", [[gameViewController view]class]);
Which are in my app delegate. The NSLog gives me "UIView". No. Why? Why would that ever be a UIView, it should be an SKView, because GameViewController was pre-written for me by apple for sprite kit. How could that possibly give me the wrong object?
I am getting 'NSInvalidArgumentException', reason: '-[UIView scene]: unrecognized selector sent to instance 0x174191780' which others have recommended to fix by putting the originalContent statement but I already have that and it isn't working.
Banner view controller:
#import "BannerViewController.h"
NSString * const BannerViewActionWillBegin = #"BannerViewActionWillBegin";
NSString * const BannerViewActionDidFinish = #"BannerViewActionDidFinish";
#interface BannerViewController () <ADBannerViewDelegate>
#end
#implementation BannerViewController {
ADBannerView *_bannerView;
UIViewController *_contentController;
}
-(instancetype)initWithContentViewController:(UIViewController *)contentController{
NSAssert(contentController != nil, #"Attempting to initialize a BannerViewController with a nil contentController.");
self = [super init];
if (self != nil) {
_bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
_contentController = contentController;
_bannerView.delegate = self;
}
return self;
}
-(void)loadView{
UIView *contentView = [[UIView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
//Have also tried SKView *contentView = [[SKView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
[contentView addSubview:_bannerView];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
self.view = contentView;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return [_contentController preferredInterfaceOrientationForPresentation];
}
-(NSUInteger)supportedInterfaceOrientations{
return [_contentController supportedInterfaceOrientations];
}
-(void)viewDidLayoutSubviews{
CGRect contentFrame = self.view.bounds, bannerFrame = CGRectZero;
bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size];
if(_bannerView.bannerLoaded){
contentFrame.size.height -= bannerFrame.size.height;
bannerFrame.origin.y = contentFrame.size.height;
}else{
bannerFrame.origin.y = contentFrame.size.height;
}
_contentController.view.frame = contentFrame;
_bannerView.frame = bannerFrame;
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
-(BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave{
[[NSNotificationCenter defaultCenter]postNotificationName:BannerViewActionWillBegin object:self];
return YES;
}
-(void)bannerViewActionDidFinish:(ADBannerView *)banner{
[[NSNotificationCenter defaultCenter]postNotificationName:BannerViewActionDidFinish object:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Game View controller:
#interface GameViewController ()
#property (nonatomic, strong) IBOutlet UIView *contentView;
#end
#implementation GameViewController {
}
-(instancetype)init{
self = [super init];
if (self) {
}
return self;
}
-(void)viewDidLoad{
//self.canDisplayBannerAds = YES;
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
-(void)viewDidLayoutSubviews{
}
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
SKView *skView = (SKView*)self.originalContentView;
if (!skView.scene) {
SKScene *scene = [GameScene sceneWithSize:skView.bounds.size];
[skView presentScene:scene];
//skView.showsPhysics = YES;
}
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskPortrait;
} else {
return UIInterfaceOrientationMaskAll;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
I figured it out. The answer, as I thought it would be, was incredibly simple and quite mind-boggling that Apple wouldn't put some sort of warning in their documentation, but then again maybe I am just too much of a noob and we are expected to know these kinds of things.
The answer, is that init was never being called in GameViewController, instead, initWithCoder: was being called. Once I NSLogged the init method and saw it wasn't being called, I figured this out.

iOS8 when to alloc init CLLocationManager to call requestWhenInUseAuthorization?

When i try to alloc init my CLLocationManager inside the getter of it i do not get the pop up request for location autorization. But when i put inside of my viewDidLoad it does work.
My code is looking like this:
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init]; //when i put this here it works
self.locationManager.delegate = self;
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if(![CLLocationManager authorizationStatus])
{
[self.locationManager requestWhenInUseAuthorization];
}
self.mapView.showsUserLocation = YES;
[self.mapView setMapType:MKMapTypeStandard];
[self.mapView setZoomEnabled:YES];
[self.mapView setScrollEnabled:YES];
}
But when i do the alloc init like this it does not work:
-(CLLocationManager *)locationManager
{
if(_locationManager) _locationManager = [[CLLocationManager alloc]init];
return _locationManager;
}
Can anyone explain to me why that is?
Because you have a logical error in your accessor method:
- (CLLocationManager *)locationManager
{
if(_locationManager == nil) _locationManager = [[CLLocationManager alloc] init];
return _locationManager;
}

MKUserTrackingBarButtonItem crashes on zoom in

I am using MKUserTrackingBarButtonItem to track user. I am not able to set the zoom when using user tracking bar button. So i tried to zoom in on the screen .
And application crashes after few steps.
I have a coordinate near by and i am trying to use this to keep track of user relative to the coordinates.
Why is app crashing.
Is there a better way to do this? Any help is greatly appreciated.
Here is my code:-
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.mapView.delegate = self;
_coordinate1.latitude = 29.9431438;
_coordinate1.longitude = -95.5170326;
self.mapView.showsUserLocation = YES; }
-(void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
MKCoordinateRegion region = [self regionFromLocations:self.currentLoc];
[self displayPoints];
MKCoordinateRegion adjustRegion = [self.mapView regionThatFits:region];
self.mapView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
[self.mapView setRegion:adjustRegion animated:YES]; }
- (void)viewDidLoad {
[super viewDidLoad];
MKUserTrackingBarButtonItem *locateMeButton = [[MKUserTrackingBarButtonItem alloc] initWithMapView:self.mapView];
NSArray *toolbarItems = [NSArray arrayWithObjects: locateMeButton,
nil];
self.toolBar.items = toolbarItems; }
- (void)viewWillDisappear:(BOOL)animated {
NSLog(#"viewwillDisapear");
[self.mapView setUserTrackingMode:MKUserTrackingModeNone];
[super viewWillDisappear:animated];}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
// getting current location
self.currentLoc = userLocation.location.coordinate;
NSLog(#"loc- %f %f", self.currentLoc.longitude, self.currentLoc.latitude); }
Solved the problem by removing map view when view Disappear
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.mapView.delegate = nil;
[self.mapView removeFromSuperview];
}

TTLauncherItem: change badge immediately (or: how to refresh TTLauncherView)

I have a TTLauncherView with some TTLauncherItems. These show badges, representing messages from the network. I set the badges in viewWillAppear:, so if I switch to another view and then return, the correct badges are shown. But I want to update the badges as soon a message comes in.
Calling setNeedsDisplay on TTLauncherView doesn't help?
How can I refresh the TTLauncherView?
in my MessageReceiver class I do this:
TTNavigator* navigator = [TTNavigator navigator];
[(OverviewController *)[navigator viewControllerForURL:#"tt://launcher"] reloadLauncherView] ;
My TTViewController-derived OverviewController
#implementation OverviewController
- (id)init {
if (self = [super init]) {
self.title = OverviewTitle;
}
return self;
}
- (void)dealloc {
[items release];
[overView release];
[super dealloc];
}
-(void)viewDidLoad
{
[super viewDidLoad];
overView = [[TTLauncherView alloc] initWithFrame:self.view.bounds];
overView.backgroundColor = [UIColor whiteColor];
overView.delegate = self;
overView.columnCount = 4;
items = [[NSMutableArray alloc] init];
for(int i = 1; i <= NumberOfBars; ++i){
NSString *barID = [NSString stringWithFormat:NameFormat, IDPrefix, i];
TTLauncherItem *item = [[[TTLauncherItem alloc] initWithTitle:barID
image:LogoPath
URL:[NSString stringWithFormat:#"tt://item/%d", i]
canDelete:NO] autorelease];
[barItems addObject: item];
}
overView.pages = [NSArray arrayWithObject:items];
[self.view addSubview:overView];
}
-(void)viewWillAppear:(BOOL)animated
{
for(int i = 0; i <[barItems count]; i++){
TTLauncherItem *item = [items objectAtIndex:i];
NSString *barID = [NSString stringWithFormat:NameFormat, IDPrefix, i+1];
P1LOrderDispatcher *dispatcher = [OrderDispatcher sharedInstance];
P1LBarInbox *barInbox = [dispatcher.barInboxMap objectForKey:barID];
item.badgeNumber = [[barInbox ordersWithState:OrderState_New]count];
}
[super viewWillAppear:animated];
}
- (void)launcherView:(TTLauncherView*)launcher didSelectItem:(TTLauncherItem*)item
{
TTDPRINT(#"%#", item);
TTNavigator *navigator = [TTNavigator navigator];
[navigator openURLAction:[TTURLAction actionWithURLPath:item.URL]];
}
-(void)reloadLauncherView
{
[overView setNeedsDisplay];//This doesn't work
}
#end
I register my Controller with the LauncherView at the AppDelegate. In my messaging class I call [appDelegate reloadLauncherView]; that again will call this
-(void)reloadLauncherView
{
[self viewWillAppear:NO ];
}
on the Controller that contains the LauncherView.
I was having a very similar problem today, (modifying a TTLauncherItem, and not seeing my changes directly) and was able to solve it by making a call to [myLauncherView layoutSubviews]; BEFORE I modified the TTLauncherItem. I actually tracked it down in the code, and this was because layoutSubviews will re-create the LauncherView's _buttons array (which is what needed to happen, in my case).