Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3 - MKPointAnnotation custom Image

This is my code and i want to add a custom pin (.png file) instead of the red pin. I tried to use MKPinAnnotationView and MKAnnotationView but i couldn't add coordinates, subtitles and title. I'm new to iOS development.

override func viewDidLoad() {
    super.viewDidLoad()
    // Handle the text field’s user input through delegate callbacks.
    commentTextField.delegate = self

    coreLocationManager.delegate = self
    //desired accuracy is the best accuracy, very accurate data for the location
    coreLocationManager.desiredAccuracy = kCLLocationAccuracyBest
    //request authorization from the user when user using my app
    coreLocationManager.requestWhenInUseAuthorization()

    coreLocationManager.startUpdatingLocation()

    dbRef = FIRDatabase.database().reference()

    struct Location {
        let title: String
        let latitude: Double
        let longitude: Double
        let subtitle: String
    }
    // Locations array
    let locations = [
        Location(title: "Dio Con Dio",    latitude: 40.590130, longitude: 23.036610,subtitle: "cafe"),
        Location(title: "Paradosiako - Panorama", latitude: 40.590102, longitude: 23.036180,subtitle: "cafe"),
        Location(title: "Veranda",     latitude: 40.607740, longitude: 23.103044,subtitle: "cafe")
    ]

    for location in locations {
        let annotation = MKPointAnnotation()

        annotation.title = location.title
        annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
        annotation.subtitle = location.subtitle

        map.addAnnotation(annotation)
    }



}
like image 722
Alex Andreadis Avatar asked May 09 '17 18:05

Alex Andreadis


2 Answers

You need to specify your view controller as the delegate for the map view (either in IB or programmatically in viewDidLoad and then (a) specify that you're conforming to the MKMapViewDelegate protocol; and (b) implement mapView(_:viewFor:):

extension ViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let identifier = "MyPin"

        if annotation is MKUserLocation {
            return nil
        }

        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)

        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView?.canShowCallout = true
            annotationView?.image = UIImage(named: "custom_pin.png")

            // if you want a disclosure button, you'd might do something like:
            //
            // let detailButton = UIButton(type: .detailDisclosure)
            // annotationView?.rightCalloutAccessoryView = detailButton
        } else {
            annotationView?.annotation = annotation
        }

        return annotationView
    }
}

For more information, see the Location and Maps Programming Guide: Creating Annotation Views from Your Delegate Object. The code snippets are in Objective-C, but it describes the basic process.

like image 183
Rob Avatar answered Oct 25 '22 10:10

Rob


Finally i did it this way, on my own!

ViewController.swift

    //
    //  ViewController.swift

    //
    //  Created by Alexandros Andreadis on 19/04/2017.
    //  Copyright © 2017 Alexandros Andreadis. All rights reserved.
    //    
    import UIKit
    import MapKit
    import CoreLocation
    import FirebaseDatabase

    class RateViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CLLocationManagerDelegate, MKMapViewDelegate{
    let pin = UIImage(named: "pin")
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
        {

            if let annotation = annotation as? Locations{
                if let view = mapView.dequeueReusableAnnotationView(withIdentifier: annotation.identifier){
                    return view
                }else{
                    let view = MKAnnotationView(annotation: annotation, reuseIdentifier: annotation.identifier)
                    view.image = pin
                    view.isEnabled = true
                    view.canShowCallout = true
                    //view.leftCalloutAccessoryView = UIImageView(image: pin)
                    return view
                }
            }
            return nil
        }
        override func viewDidLoad() {
            super.viewDidLoad()

            mapView.delegate = self 

            mapView.addAnnotations(locations)



        }


    }

Locations.swift

//
//  Locations.swift

//
//  Created by Alexandros Andreadis on 10/05/2017.
//  Copyright © 2017 Alexandros Andreadis. All rights reserved.
//

import UIKit
import MapKit

class Locations: NSObject, MKAnnotation {
    // required coordinate, title, and the reuse identifier for this annotation
    var identifier = "locations"
    var title: String?
    var coordinate: CLLocationCoordinate2D
    //initializer taking a name, a latitude and longitude to populate the title and coordinate for each instance of this object
    init(name:String,lat:CLLocationDegrees,long:CLLocationDegrees){
        title = name
        coordinate = CLLocationCoordinate2DMake(lat, long)
    }

}
// Creating the list of the places that will be pinned in map
class LocationList: NSObject {
    var Location = [Locations]()
    override init(){
        Location += [Locations(name: "Dio Con Dio", lat: 40.590130, long: 23.036610)]
        Location += [Locations(name: "Paradosiako - Panorama", lat: 40.590102, long:23.036180)]
        Location += [Locations(name: "Veranda",  lat: 40.607740, long: 23.103044)]
        Location += [Locations(name: "Markiz",  lat: 40.634252, long: 22.936276)]
        Location += [Locations(name: "Moi Lounge Bar",  lat: 40.653481, long: 22.994131)]
        Location += [Locations(name: "Boulevard Lounge Bar",  lat: 40.658462, long: 22.983198)]
        Location += [Locations(name: "Ernést Hébrard",  lat: 40.631829, long: 22.941014)]
        Location += [Locations(name: "Tribeca - All Day & Night Bar",  lat: 40.631029, long: 22.942396)]

    }
}
like image 22
Alex Andreadis Avatar answered Oct 25 '22 10:10

Alex Andreadis