MKPinAnnotationView not showing title

1.2k views Asked by At

I've had some past experience using MKMapView and MKPointAnnotation, which I used to put some pin on a map. This time I am trying to go one step further and use MKPinAnnotationView, to write a label along with some of the pins.

Unfortunately, it doesn't all work as I expect.

Here is what I want to do:

I have a map (an MKMapView object) and when I touch it, I put a pin at the touch point, then some computation is performed and this gives me a second point on the map. I put a second pin(located at the second point), on this last pin I want to put a label, say "Hello Second!".

Here is the relevant code:

class ViewController: UIViewController, MKMapViewDelegate {
    var mapView:MKMapView!, touchPoint,secondPoint:MKPointAnnotation!

    override func viewDidLoad() {
        super.viewDidLoad()
        mapView = MKMapView()
        ...........
        let mapTap = UITapGestureRecognizer(target: self,
                                            action: #selector(ViewController.mapTouchHandler))
        mapView.addGestureRecognizer(mapTap)
    }


    func mapTouchHandler(gesture:UITapGestureRecognizer) {
        ...........
        // Compute map coordinates for the touch point (tapGeoPoint).

        if touchPoint == nil {
            touchPoint = MKPointAnnotation()
            mapView.addAnnotation(touchPoint);
        }

        touchPoint.coordinate = CLLocationCoordinate2D(latitude: tapGeoPoint.latitude,
                                                       longitude: tapGeoPoint.longitude)
        ...........
        computeSecondPoint(url: someComputedURL)
    }


    func computeSecondPoint(url searchURL:String) {
        let reqURL = NSURL(string: searchURL)!, session = URLSession.shared,
        task = session.dataTask(with: reqURL as URL) {
            (data: Data?, response: URLResponse?, error: Error?) in
            if error == nil {
                do {let allData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray
                    .................
                    // Compute map coordinates for the second point (secondPointCoord).

                    if self.secondPoint == nil {
                        self.secondPoint = MKPointAnnotation()
                        self.mapView.addAnnotation(self.secondPoint)
                    }

                    DispatchQueue.main.async {
                        () -> Void in
                        self.secondPoint.coordinate = CLLocationCoordinate2D(latitude: secondPointCoord.latitude,
                                                                             longitude: secondPointCoord.longitude)
                        self.secondPoint.title = "Hello Second!"
                    }
                } catch let error as NSError {print(error.localizedDescription)}
            } else {
                print("Error inside \(#function):\n\(error)")
            }
        }

        task.resume()

    }


    func mapView(_ mapView: MKMapView,
                 viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let identifier = "pin"
        var view: MKPinAnnotationView
        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
            as? MKPinAnnotationView {
            dequeuedView.annotation = annotation
            view = dequeuedView
        } else {
            view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            view.canShowCallout = true
            view.calloutOffset = CGPoint(x: -5, y: 0)
        }
        return view
    }
}

Now here is what happens, the pins are placed as expected, but I do not see any label on the second one. I also noticed that if I tap where the second pin happens to be (in that case the 2nd pin will stay at the same place) then the label appears (as it should always do). If I tap again (not so near), then the label disappears again(though it shouldn't).

Is there something in my code (above) that is not right? Any relevant tip will be appreciated.

3

There are 3 answers

2
hussain On

This i'have used for Google map, but it should work for u..

let position = CLLocationCoordinate2DMake(latitude,longitude)
let location = GMSMarker(position: position)
location.icon = image
location.icon? = self.imageWithImage(image, scaledToSize: CGSize(width: 50.0, height: 50.0))
location.title = "the photo is clicked here!!"
location.map = MapView
6
Vishnu gondlekar On

Title you are referring to in

self.secondPoint.title = "Hello Second!"

is the title of callout view which comes when you tap the annotation pin. If you want to show label along with the pin image every time you can probably subclass MKAnnotationView and add label there in your custom pin view. You can customise in following way

class CustomAnnotationView : MKPinAnnotationView
{
    let helloLabel:UILabel = UILabel.init(frame:CGRectMake(0, 0, 100, 40)) //your desired frame

    func showLabel(title : String)
    {
        helloLabel.text = title
        helloLabel.textAlignment = .Center
        //set further properties
        self.addSubview(helloLabel)
    }

    fun hideLabel() {
        helloLabel.removeFromSuperview()
    }
}
0
Nishant Chandwani On

Try This Solution This will be help you

First Create MyAnnotation pin

if(geo_accuracy == "0")
            {
                colorofpin = .Blue
            }else if (geo_accuracy == "1")
            {
                colorofpin = .Red
            }else
            {
                colorofpin = .Green
            }
            var locationAnnotation = MyAnnotation(coordinate: location,
                title: p_user_name!,
                subtitle: "",
                pinColor: colorofpin,
                getTag:i)


            /* And eventually add them to the map */

            //aryNotation.addObject(locationAnnotation)

            aryNotation.append(locationAnnotation)

mapview Delegate method

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

            if annotation is MyAnnotation == false{
                return nil
            }

            /* First typecast the annotation for which the Map View has
            fired this delegate message */
            let senderAnnotation = annotation as! MyAnnotation



            // --------------------------    For ios 9 -------------------


            let reuseId = "pin"
            var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)

            if pinView == nil {
                pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
                pinView!.canShowCallout = true

            }else{
                pinView!.annotation = annotation
            }
            pinView!.tag = senderAnnotation.getTag;

          //  print(senderAnnotation.getTag)

            if annotation is MyAnnotation {

                //print(senderAnnotation.pinColor)
                if(senderAnnotation.pinColor == .Red)
                {
                    if(currentIndex == senderAnnotation.getTag)
                    {
                        //print("currentIndex==\(currentIndex)********")
                        pinView!.image = UIImage(named: "jivemap_pin_rough_o.png")
                        pinView!.layer.zPosition = 1
                        pinView?.bringSubviewToFront(self.view)
                       // pinView!.superview!.bringSubviewToFront(view)
                    }else
                    {
                        pinView!.image = UIImage(named: "jivemap_pin_rough_g.png")
                        pinView!.layer.zPosition = 0
                    }
                }
                else
                {

                if(currentIndex == senderAnnotation.getTag)
                {
                    //print("currentIndex==*********\(currentIndex)********")
                    pinView!.image = UIImage(named: "jivemap_pin_o.png")
                    pinView!.layer.zPosition = 1


                }else
                {
                    pinView!.image = UIImage(named: "jivemap_pin_g.png")
                    pinView!.layer.zPosition = 0
                }
            }

                pinView!.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure) as UIView
              // pinView
               // return pinView
            }





            return pinView
            //return annotationView

    }

This is my annation class. This class will fullfil your all problem

import UIKit
import MapKit

/* This will allow us to check for equality between two items
of type PinColor */
func == (left: PinColor, right: PinColor) -> Bool{
    return left.rawValue == right.rawValue
}

/* The various pin colors that our annotation can have */
enum PinColor : String{
    case Blue = "Blue"
    case Red = "Red"
    case Green = "Green"
    case Purple = "Purple"

    /* We will convert our pin color to the system pin color */
    func toPinColor() -> MKPinAnnotationColor{
        switch self{
        case .Red:
            return .Red
        case .Green:
            return .Green
        case .Purple:
            return .Purple
        default:
            /* For the blue pin, this will return .Red but we need
            to return *a* value in this function. For this case, we will
            ignore the return value */
            return .Red
        }
    }
}

class MyAnnotation: NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    var title: String?
    var subtitle: String?
    var pinColor: PinColor!
    var getTag:Int!
    var annoationIndex = 0

    init(coordinate: CLLocationCoordinate2D,
        title: String,
        subtitle: String,
        pinColor: PinColor,
        getTag: Int){
            self.coordinate = coordinate
            self.title = title
            self.subtitle = subtitle
            self.pinColor = pinColor
            self.getTag = getTag
            super.init()
    }

    convenience init(coordinate: CLLocationCoordinate2D,
        title: String,
        subtitle: String,
        gettag: Int){
            self.init(coordinate: coordinate,
                title: title,
                subtitle: subtitle,
                pinColor: .Blue,
                getTag: gettag)
    }

}