Keep two MKMapViews showing the same region

2019-02-25 11:17发布

问题:

On my iPad app, I have 2 mapViews that are the same size displayed next to each other. I want these to always show the same area. I achieve this now using the regionDidChangeAnimated: delegate method.

This does not always work that great (sometimes the regions are different after zooming) and there is a lag between the user moving one of the maps and the other one moving.

Is there a good way to duplicate the touches across both maps so that as a user is panning and zooming on one, it will automatically do the same thing on the other map at the same time?

One thing I looked at was creating a UITouch object with the same location value as the ones being crating in the map that is being moved, but that is not really a good solution.

Is there a way to just duplicate a set of touches on one UIView to another (since MKMapView is a UIView)?

Thanks, Ross

回答1:

You could use UIGestureRecognizer to help keep the maps more in sync as the user is manipulating one of the maps.

For example, using the UIPanGestureRecognizer, the gesture recognizer action handler will fire multiple times while the user is panning the map--unlike regionDidChangeAnimated which fires only when the pan is finished.

You'll need to add a gesture recognizer to one or both maps and implement your custom gesture handler method. Also implement the shouldRecognizeSimultaneouslyWithGestureRecognizer delegate method and return YES so your gesture handler can work together with the map's.

Example:

//add the gesture handler to map(s)...
UIPanGestureRecognizer *pgr = [[UIPanGestureRecognizer alloc] 
    initWithTarget:self action:@selector(gestureHandler:)];
pgr.delegate = self;
[mapViewA addGestureRecognizer:pgr];
[pgr release];

//...

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
    shouldRecognizeSimultaneouslyWithGestureRecognizer:
        (UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

- (void)gestureHandler:(UIGestureRecognizer *)gestureRecognizer
{
    [mapViewB setRegion:mapViewA.region animated:NO];
}

If you want to add the gesture recognizer to both, you'll need to create a separate instance for each map (ie. you can't add pgr to both maps). You might also want/need to add UIPinchGestureRecognizer and UITapGestureRecognizer. You can use the same handler method for all the recognizers though.

I'd still implement regionDidChangeAnimated just in case a gesture is missed.



回答2:

try to think about using one static variable and one static function to control the zoomlevel



回答3:

If you do not develop for the App store, you can use private API to synthesize touches.
See http://cocoawithlove.com/2008/10/synthesizing-touch-event-on-iphone.html.

You can intercept, duplicate and modify touch events by overriding [UIApplication sendEvent:]. I have not tested it should work, although you cannot submit for the App Store.