Question

I'm trying to keep the info window from disappearing. To show it I've used

[mapView_ setSelectedMarker:marker];

But when the user taps the map somewhere the info window disappears. I've tried re-setting it at didTapAtCoordinate but this is called before deselecting any markers. How to do it?

Was it helpful?

Solution 2

Key Value Observing is the design pattern for this case. This answer works for me.

- (void)viewDidLoad {
  [super viewDidLoad];
  self.shouldShowInfoView = NO;
  [self.mapView addObserver:self
            forKeyPath:@"selectedMarker"
               options:(NSKeyValueObservingOptionNew |
                        NSKeyValueObservingOptionOld)
               context:NULL];
}

- (void)needToShowInfoView {
  self.shouldShowInfoView = YES;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {

  if ([keyPath isEqual:@"selectedMarker"]) {
    if (self.shouldShowInfoView) {
      if ([[change objectForKey:NSKeyValueChangeNewKey] isKindOfClass:[NSNull class]]) {
        self.mapView.selectedMarker = [change objectForKey:NSKeyValueChangeOldKey];
      }
    }
  }
}

OTHER TIPS

For anyone wanting to test out Hanton's solution in Swift 4, simplified to just always show the info window as soon as the page is loaded:

override func viewDidLoad() {
    mapView.addObserver(self, forKeyPath: "selectedMarker", options: [.new, .old], context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "selectedMarker" {
        if change?[.newKey] as? NSObject is NSNull {
            mapView.selectedMarker = change?[.oldKey] as? GMSMarker
        }
    }
}

This does work, though there is a brief flash of the info window disappearing and reappearing when the user taps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top