2011-05-15 19 views
10

Si pellizca para acercar o alejar la aplicación Apple Maps mientras rastrea la ubicación del dispositivo, se ignora el componente "panorámica" del gesto de pellizco y el indicador de ubicación azul permanece fijo en el centro del pantalla. Este no es el caso cuando se usa un simple MKMapView.Mantener la coordenada central mientras pellizca MKMapView

Suponiendo que ya tengo la ubicación del usuario, ¿cómo podría lograr este efecto? Intenté restablecer la coordenada central en los métodos regionDid/WillChangeAnimated: del delegado, pero solo se llaman al inicio y al final del gesto. También traté de agregar una subclase UIPinchGestureRecognizer que restablece la coordenada central cuando se mueven los toques, pero esto dio como resultado fallas técnicas en la representación.


Editar: Para aquellos que estén interesados, las siguientes obras para mí.

// CenterGestureRecognizer.h 
@interface CenterGestureRecognizer : UIPinchGestureRecognizer 

- (id)initWithMapView:(MKMapView *)mapView; 

@end 

// CenterGestureRecognizer.m 
@interface CenterGestureRecognizer() 

- (void)handlePinchGesture; 

@property (nonatomic, assign) MKMapView *mapView; 

@end 

@implementation CenterGestureRecognizer 

- (id)initWithMapView:(MKMapView *)mapView { 
    if (mapView == nil) { 
    [NSException raise:NSInvalidArgumentException format:@"mapView cannot be nil."]; 
    } 

    if ((self = [super initWithTarget:self action:@selector(handlePinchGesture)])) { 
    self.mapView = mapView; 
    } 

    return self; 
} 

- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { 
    return NO; 
} 

- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { 
    return NO; 
} 

- (void)handlePinchGesture { 
    CLLocation *location = self.mapView.userLocation.location; 
    if (location != nil) { 
    [self.mapView setCenterCoordinate:location.coordinate]; 
    } 
} 

@synthesize mapView; 

@end 

Después, simplemente añadirlo a su MKMapView:

[self.mapView addGestureRecognizer:[[[CenterGestureRecognizer alloc] initWithMapView:self.mapView] autorelease]]; 

Respuesta

5

Cuando el usuario aprieta la pantalla en el dispositivo real (en comparación con el simulador), que provoca tanto una sartén un gesto y pizca - el pellizco contiene el elemento de "zoom" de la moción, y la bandeja contiene el cambio vertical y horizontal. Debe interceptar y bloquear la bandeja, y eso significa usar un UIPanGestureRecognizer.

Establezca scrollEnabled en NO, luego agregue UIPanGestureRecognizer para restablecer la coordenada central. La combinación bloqueará tanto el barrido de un solo dedo como el componente de bandeja de una pizca.


Editar para añadir más detalles, y después de ver su código: touchesMoved:withEvent se llama después de la sartén ya ha comenzado, por lo que si se cambia el centro de la MKMapView ahí, obtendrá los problemas de renderizado herky-espasmódicos usted ha descrito. Lo que realmente necesita es crear un UIPanGestureRecognizer con una meta de la acción, así:

UIPanGestureRecognizer *pan = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didRecognizePan)] autorelease]; 
    pan.delegate = self; 
    [self.mapView addGestureRecognizer:pan]; 

... y luego añadir un método didRecognizePan a su controlador, y hacer su centro de reposición allí.

+0

Esto dio como resultado los mismos problemas de representación que se mencionaron anteriormente: el centro de la vista de mapa alterna con frecuencia entre la ubicación del usuario y dónde se ubicaría si los reconocedores de gestos siguieran su curso. Quizás he entendido mal tu respuesta? He publicado la implementación de mi subclase 'UIPanGestureRecognizer' aquí: http://pastie.org/1934011 –

+0

¡Eso funcionó! Me alegra que la solución fuera tan simple. Gracias, Scott. –

0

Sólo una conjetura, pero ¿ha intentado fijar scrollEnabled a NO al comienzo de regionWillChangeAnimated:?

+0

Desafortunadamente eso no funcionó. Si configuro 'NO' al inicio (fuera de los métodos de delegado), el desplazamiento con un solo dedo está desactivado, pero los componentes "panorámicos" de los gestos de pellizco todavía se usan. –

0

Solo una conjetura también. Al comienzo de la regiónWillChangeAnimated: guarde la región del mapa actual, luego actualice continuamente la región a través de un NSTimer usando self.myMapView.region = theSavedRegion o similar. A continuación, invalide el temporizador cuando se llame a regionDidChangeAnimated:

Sin embargo, es posible que tenga un problema en el que la actualización de región realizada por NSTimer haga que se llame de nuevo a regionWillChangeAnimated.

Pruébalo y mira lo que sucede.

+0

Sospecho que esto dará como resultado los mismos fallos de representación que se mencionaron en la pregunta; efectivamente está haciendo lo mismo, solo con un temporizador en lugar de un 'UIGestureRecognizer'. Investigaré e informaré si tengo éxito. –

+0

Jugué un poco tratando de interceptar gestos de desplazamiento, pero eso no pareció funcionar. ¡Buena suerte, no puedo esperar para escuchar cuál es la solución! – timthetoolman

Cuestiones relacionadas