2

I am trying a quick prototype project to see if what I want to do with Mapbox iOS SDK (route-me) and iOS MapKit is possible.

I would like to see if I can have the best of both worlds with MapBox's offline capability (and extras like clustering) but also still use the iOS map types. After some research (and help on SO) I found that Mapbox and iOS maps do not work together, you get to pick one or the other. I started to wonder what would happen if I lay a RMMapView (mapbox map) directory on top of the iOS map. Then in instances when I want to see the iOS map I could just set the RMMapViews basemap to transparent such that the iOS map directly beneath it would show through. Again two fold, you could use iOS maps if you wanted but I could also keep the mapbox markers drawn such that when you switch to the iOS map you do not need to re-draw markers.

enter image description here

Basically I have created a main view (Super View) and added two subviews (MKMapView and RMMapView), with RMMapView on top. I have already figured out how to make the base layer on the RMMapView transparent, and I can even add RMMarkers and they show nicely laid on top of the MKMapView.

My problem is with touch events and gestures. If I do this I need all touches and gestures that happen on the RMMapView, to still happen on the RMMapView but also happen on the MKMapView. I.E. if the base map on RMMapView is transparent but there is a marker in that view, when I scroll the map I need the RMMapView to move (such that the marker moves) along with the MKMapView.

What I have tried:

  1. Override hitTest. Problem with this approach is that once you do this the touch will only operate on the view you return. I need the touch to happen on both the RMMapView and the MKMapView.
  2. Created a gesture recognizer in my Super View. I then try to pass the touches on to both of my sub views. Really, really though this might work. But there are a couple problems from what I can tell. First I know both map views have scroll views on top of them so forwarding the touch to the MKMapView and RMMapView does not work. I think I would have to forward the touch to each maps scroll view.

So I don't think 1 would ever work, and I cannot get 2 to work. Anyone ever tried to do anything like this. Can 2 different view act on the same touch events or does the first view that gets the event win?

My design may be wrong too so if anyone has another suggestion please throw it out. Do realize though that I would like to stay away from modifying RMMapView, and cannot really mod MKMapView.

Most relevant post I could find was this: How to intercept touches events on a MKMapView or UIWebView objects?. But I don't want to intercept events on the MKMapView, I want to intercept them on the SuperView such that I can pass to both its sup views.

Thanks

Community
  • 1
  • 1
lostintranslation
  • 23,756
  • 50
  • 159
  • 262

2 Answers2

0

I am not sure to fully understand your need but touch events are automatically propagated along the responder chain. If you want to handle it you just have to override those methods

– touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
– touchesCancelled:withEvent:

and just call [super touchesBegan..] in your implementation.

It is explained in the UIResponder class reference doc:

Discussion The default implementation of this method does nothing. However immediate UIKit subclasses of UIResponder, particularly UIView, forward the message up the responder chain. To forward the message to the next responder, send the message to super (the superclass implementation); do not send the message directly to the next responder. For example,

[super touchesBegan:touches withEvent:event];

Is that what you need?

Vincent Zgueb
  • 1,491
  • 11
  • 11
  • I tried to override those methods in my SuperView and then pass them along to both the MKMapView and RMMapView. However overiding those and passing the events on to even just the MKMapView seems to cause an infinite loop. – lostintranslation Feb 23 '14 at 13:48
  • You can only use the responder chain method to pass your event. It is made for you by the UIView. Do not try to hack this. It won't work. – Vincent Zgueb Feb 23 '14 at 15:16
  • Sounds great, but my questions still stand. 1. I tried to override the responder chain methods and when I pass the event to the MKMapView it causes an infinite loop. I would just like both the MKMapView and the RMMapView to respond to the event. I.E. if I scroll the map, they both scroll. – lostintranslation Feb 23 '14 at 19:59
  • Your statement 'I am not sure to fully understand your need'. With RMMapView on top it gobbles up all the touch events and gestures. I need it to react to those touch events but all so pass them along to its sibling view. Instead of trying to pass to the sibling view I am trying to intercept the events in the super view and let the super view pass those events along to its children. I need both children of the SuperView to do something with the events. – lostintranslation Feb 23 '14 at 21:19
  • Did you ever figure out a solution to this? – CommaToast May 12 '15 at 20:07
0

I'm the maintainer of the Mapbox iOS SDK (i.e. the RMMapView part of this).

I haven't tried this, but you could try making use of the region/center/zoom change delegate methods on one side or the other to drive updates to the opposing map. I would maybe try this with Mapbox -> MapKit first, since Mapbox has finer-grained callbacks.

One other thing I would try is using GCD to dispatch_async() these calls so as to not tie up the delegate callback.

This approach could be totally ill-advised but I figured I'd throw it out there.

I don't think you'll have much luck with shared touch events.

incanus
  • 5,100
  • 1
  • 13
  • 20