1

I am creating a map application which allows emojis to be attached to locations. Currently, the image is displayed above the stock apple map annotation.

I wish to hide the stock pin image while still displaying the selected emoji by the user. Is this possible?

enter image description here

I have this code so far to perform this:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    //let identifier = "MyPin"

    if annotation.isKindOfClass(MKUserLocation) {
        return nil
    }

    let dictName = arrLocation[((annotation as? MyAnnotation)?.index)!]
    let imgName = dictName.valueForKey("pin_img") as? String
    var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(imgName!)
    if annotationView == nil
    {
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: imgName)
        annotationView!.canShowCallout = false
        let name = dictName.valueForKey("name") as! String
        let annot = MyAnnotation(titleName:name)
        annotationView?.annotation = annot

    }
    else
    {
        annotationView!.annotation = annotation
    }

    let detailButton: UIButton = UIButton(type: UIButtonType.Custom)
    // size and placement of emoji on map
    detailButton.frame = CGRectMake(-34,-25,85,85)
    detailButton.tag = ((annotation as? MyAnnotation)?.index)!
    detailButton.addTarget(self, action:"emojiTap:", forControlEvents: UIControlEvents.TouchUpInside)
    detailButton.setBackgroundImage(UIImage(named:(dictName.valueForKey("pin_img") as? String)!), forState: UIControlState.Normal)
    annotationView!.addSubview(detailButton)

    return annotationView
}
Oscar
  • 511
  • 2
  • 10
  • 25
  • 1
    In your code above, if you don't successfully dequeue an annotation view, you create one, but you assign its `annotation` to be a new `MyAnnotation`. You should use the `annotation` that was passed to this method. Also, where you create the `pin_img`, it will be easier if you just set the `image` property of the `MKPinAnnotationView`. – Rob Jul 10 '16 at 04:38

1 Answers1

1

Custom annotation view

Instead of using an MKPinAnnotationView, use its superclass MKAnnotationView.

Responding to input

To respond to the user tapping on an annotation implement the mapView:didSelectAnnotation: delegate method. This delegate method is called when the annotation is tapped.

Note that you do not need to use the button inside the annotation view. This means the functionality in emojiTap: must be implemented by the mapView:didSelectAnnotation: method.

Example

Combining these

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    if annotation.isKindOfClass(MKUserLocation) {
        return nil
    }

    let dictName = arrLocation[((annotation as? MyAnnotation)?.index)!]
    let imgName = dictName.valueForKey("pin_img") as? String
    var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(imgName!)

    if annotationView == nil
    {
        annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: imgName)
        let name = dictName.valueForKey("name") as! String
        let annot = MyAnnotation(titleName:name)
        annotationView?.annotation = annot    
    }
    else
    {
        annotationView!.annotation = annotation
    }

    annotationView!.canShowCallout = false

    return annotationView
}

func mapView(_ mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    
    guard let annotation = view.annotation as? MyAnnotation else {
        return
    }

    print("tapped annotation: \(annotation.index)

    // Implement the code from emojiTap: here.
}
arc4randall
  • 3,275
  • 3
  • 27
  • 40
Luke Van In
  • 5,215
  • 2
  • 24
  • 45
  • Great, this removes the pin! However I seem to be having trouble selecting the dropped emojis now :( Any suggestion? – Oscar Jul 10 '16 at 03:17
  • That is just another `MKMapViewDelegate` method, so it can go into the same file as your `mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation)`. – Luke Van In Jul 10 '16 at 13:17
  • I get errors when I try to implement :( "Invalid redeclaration of 'mapView(_didselectannotationview:)'" – Oscar Jul 10 '16 at 13:20
  • Changed the name of func, but still annotations cannot be selected :( When the user presses and holds their finger on the emoji, a popover view will be displayed – Oscar Jul 10 '16 at 13:22
  • @Oscar All that error means is that you already have `didSelectAnnotationView`. You can just use your existing method rather than trying to add another one. I have updated the answer to try explain this more clearly. Basically instead of using `emojiTap`, you use `didSelectAnnotationView`. The button inside the annotation view is not needed. If this still doesn't make sense, feel free to continue in chat. – Luke Van In Jul 10 '16 at 13:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/116924/discussion-between-luke-van-in-and-oscar). – Luke Van In Jul 10 '16 at 13:33