James Zaghini
James Zaghini

Reputation: 4001

MKAnnotationView - hard to drag

I have a MKAnnotationView that the user can drag around the map.

It is very difficult for a user to drag the pin. I've tried increasing the frame size and also using a giant custom image. But nothing seems to actually change the hit area for the drag to be larger than default.

Consequently, I have to attempt to tap/drag about ten times before anything happens.

MKAnnotationView *annView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"bluedot"] autorelease];

UIImage *image = [UIImage imageNamed:@"blue_dot.png"];

annView.image = image;
annView.draggable = YES;
annView.selected = YES;
return annView;

What am I missing here?

EDIT:

It turns out the problem is that MKAnnotationView needs to be touched before you can drag it. I was having trouble because there are a lot of pins nearby and my MKAnnotationView is very small.

Upvotes: 2

Views: 619

Answers (3)

mylogon
mylogon

Reputation: 2959

Just came here to say this still helped me today, multiple years later. In my application, the user can place a bounding area down with annotations and (hopefully) move them around freely. This turned out to be a bit of a nightmare with this "select first and then move" behaviour and just plain made it difficult and infuriating.

To solve this, I default annotation views to selected

func mapView(_ mapView: MKMapView,
             viewFor annotation: MKAnnotation) -> MKAnnotationView? {
  let view = MKAnnotationView(annotation: annotation, reuseIdentifier: "annotation")
  view.isDraggable = true
  view.setSelected(true, animated: false)
     
  return view
}

The problem is that there is an annotation manager that resets all annotations back to deselected, so I get around this in this delegate method

func mapView(_ mapView: MKMapView,
             annotationView view: MKAnnotationView,
             didChange newState: MKAnnotationView.DragState,
             fromOldState oldState: MKAnnotationView.DragState) {
  
  if newState == .ending {
    mapView.annotations.forEach({
      mapview.view(for: $0)?.setSelected(true, animated: false)
    })
  }

It's a stupid hack for a stupid problem. It does work though.

Upvotes: 0

Radu
Radu

Reputation: 1

Instead of using a timer, you could select the annotation on mouse down. This way you don't mess with the annotation selection, and don't have a timer for each annotation running all the time.

I had the same problem when developing a mac application, and after selecting the annotation on mouse down, the drag works great.

Upvotes: 0

James Zaghini
James Zaghini

Reputation: 4001

I didn't realise MKAnnotationView needed to be touched before you can drag it.

To get around this, I created a timer that selected that MKAnnotationView regularly.

NSTimer *selectAnnotationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(selectCenterAnnotation) userInfo:nil repeats:YES] retain];  

and the method it calls:

- (void)selectCenterAnnotation {
    [mapView selectAnnotation:centerAnnotation animated:NO];    
}    

Upvotes: 1

Related Questions