2011-12-27 14 views
8

Actualmente tengo una vista de mapa con algunas anotaciones sobre ella. Tengo la anotación con imágenes personalizadas. El problema que intento corregir es la sensibilidad de las imágenes. Cuando intento arrastrarlos, siento que tengo que tocar el centro exacto para enfocarlo. ¿Hay alguna manera de hacer que los límites táctiles sean más grandes?¿Cómo hago que un MKAnnotationView sea sensible al tacto?

Respuesta

17

Para hacer esto, necesita crear la subclase MKAnnotationView para crear su propia MKAnnotationView personalizada. En su subclase, anule las siguientes funciones:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event 
{ 
    // Return YES if the point is inside an area you want to be touchable 
} 

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event 
{ 
    // Return the deepest view that the point is inside of. 
} 

Esto permite presionar las vistas interactivas (como botones, etc.). La implementación predeterminada en MKAnnotationView no es estricta en pointInside y hitTest porque permite que las prensas que están realmente dentro de una anotación se envíen a una anotación diferente. Esto se consigue calculando el centro de anotación más cercano al punto de contacto y enviando los eventos a esa anotación, esto es para que las anotaciones cercanas (superpuestas) no se bloqueen entre sí. Sin embargo, en su caso, es probable que desee bloquear otras anotaciones si el usuario debe seleccionar y arrastrar la anotación más alta, por lo que el método anterior es probablemente lo que desea o, de lo contrario, lo establecerá en la ruta correcta.

EDIT: me pidieron en comentarios para un ejemplo de implementación hitTest:withEvent: - Esto depende de exactamente lo que usted está tratando de lograr. La pregunta original sugería tocar y arrastrar imágenes dentro de la anotación, mientras que en mi caso tengo algunos botones dentro de la anotación que quiero que sean interactivos.Aquí está mi código:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event 
{ 
    UIView* hitView = [super hitTest:point withEvent:event]; 
    if (hitView != nil) 
    { 
     // ensure that the callout appears above all other views 
     [self.superview bringSubviewToFront:self]; 

     // we tapped inside the callout 
     if (CGRectContainsPoint(self.resultView.callButton.frame, point)) 
     { 
      hitView = self.resultView.callButton; 
     } 
     else if (CGRectContainsPoint(self.resultView.addButton.frame, point)) 
     { 
      hitView = self.resultView.addButton; 
     } 
     else 
     { 
      hitView = self.resultView.viewDetailsButton; 
     } 
     [self preventSelectionChange]; 
    } 
    return hitView; 
} 

Como se puede ver que es bastante simple - El MKAnnotationView aplicación (llamado como super en la primera línea de mi aplicación) sólo devuelve el primer punto de vista (más externa), no tiene niveles inferiores de los ver jerarquía para ver en qué subvista se encuentra realmente el toque. En mi caso, solo compruebo si el toque está dentro de uno de los tres botones y los devuelvo. En otras circunstancias, puede tener una perforación basada en un rectángulo simple a través de la jerarquía o pruebas de detección más complejas, por ejemplo, para evitar áreas transparentes dentro de su vista para permitir que los toques pasen por esas partes. Si necesita profundizar, se puede usar CGRectContainsPoint de la misma manera que lo he usado, pero recuerde compensar sus puntos en coordenadas de vista local para cada nivel de vista que explora.

El método preventSelectionChange es evitar que mi anotación personalizada se seleccione, la estoy usando como una leyenda personalizable/interactiva desde los pines del mapa y esto mantiene el pin relacionado a seleccionado en lugar de permitir que la selección cambie a esta anotación.

+0

¿Podría implementar el método hitTest por favor? – Daniel

+0

¡Si pudiera volver a votar su respuesta otra vez lo haría! Gracias por la actualización. – Daniel

+0

Hola otra vez, ¿qué tal pointInside: withEvent:? ¿Es aquí donde propones que se implemente CGRectContainsPoint? – Daniel

0

he implementado algo similar de la siguiente manera

  1. Crear una subclase de la clase de gestos Reconocedor que maneja toques
  2. crear una subclase de la clase UIImage, esta clase utiliza la clase reconocedor para manejar sus gestos
  3. Utilice esta en la anotación

el gesto reconocedor subclase manejará sus gestos si los realiza en cualquier punto de la ima ge. Esto debería ayudarte.

nos mantienen informados de si esta solución funcionó para u ...

1

Quizás quiso subclase MKAnnotationView o ¿Ha cambiado la acaba de establecer la propiedad de imagen de ella?

Aquí está la documentación para establecer la propiedad de la imagen.

Discusión: Asignación de una nueva imagen a esta propiedad también cambia el tamaño del marco de la vista para que coincida con la anchura y la altura de la nueva imagen. La posición del marco de la vista no cambia.

Compruebe el tamaño del marco de la vista de anotación, que es donde su objeto puede recibir toques.

0

@jhabbott solución nunca funcionó para mí, como mencioné here.

Tengo una imagen y una etiqueta una al lado de la otra. La imagen se demostró mediante el establecimiento de annotationview image propiedad, y la etiqueta mediante la adición de un UILabel

I redirigido el método func point(inside:with:) a la UILabel uno (que incluía la zona de imagen) y hitTest arrojó exactamente la misma vista si he hecho clic en el etiqueta o la imagen. Pero etiqueta de clic no produjo ninguna devolución de llamada ...

Finalmente, terminaron mediante la ampliación del marco de MKAnnotationView para encerrar etiqueta + imagen, me puse a annotationView.imagenil, y creé mi costumbre UIImageView.

Porque quería el punto de anclaje en el centro de la imagen, que tuvieron que establecer una personalizada:

self.frame = CGRect(x: 0, y: 0, width: 
self.myLabel.frame.width, height: self.myLabel.frame.height) 
self.centerOffset = CGPoint(x: self.frame.width/2, y: self.myImageView.frame.height/2) 

Entonces yo borrado point(inside:with:) y hitTest(point:with:) anulaciones que no hicieron nada.

Y ahora, por primera vez, mi vista de anotación es completamente reactiva.

Cuestiones relacionadas