How to change MapKit's pin color in Swift 3/4? - ios

So, I am creating an app with MapKit. So, I need some help of changing the maps pin color from red to any color possible. I tried every way, I can't just not find a solution. Can any one check my code, and help me apply it to my code below of changing the map's pin tintColor. Thanks in advance.
Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.count > 0 {
let location = locations.last!
print("Accuracy: \(location.horizontalAccuracy)")
if location.horizontalAccuracy < 100 {
manager.stopUpdatingLocation()
let span = MKCoordinateSpan(latitudeDelta: 0.014, longitudeDelta: 0.014)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.region = region
let location = CLLocation(latitude: latitude, longitude: longitude)
let place = Place(location: location, reference: reference, name: name, address: address)
self.places.append(place)
let annotation = MyHome(location: place.location!.coordinate, title: place.placeName)
DispatchQueue.main.async {
self.mapView.addAnnotation(annotation)
}
}
}
}
}
}
}
}
}
MyHome CLass
import Foundation
import MapKit
class MyHome: NSObject, MKAnnotation {
let coordinate: CLLocationCoordinate2D
let title: String?
init(location: CLLocationCoordinate2D, title: String) {
self.coordinate = location
self.title = title
super.init()
}
}
MapView
fileprivate var locationManager = CLLocationManager()
fileprivate var heading: Double = 0
fileprivate var interactionInProgress = false
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
{
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required public init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
open override func viewDidLoad()
{
super.viewDidLoad()
self.mapView.isRotateEnabled = false
if let annotations = self.annotations
{
addAnnotationsOnMap(annotations)
}
locationManager.delegate = self
}
open override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
locationManager.startUpdatingHeading()
}
open override func viewDidDisappear(_ animated: Bool)
{
super.viewDidDisappear(animated)
locationManager.stopUpdatingHeading()
}
open func addAnnotations(_ annotations: [ARAnnotation])
{
self.annotations = annotations
if self.isViewLoaded
{
addAnnotationsOnMap(annotations)
}
}
fileprivate func addAnnotationsOnMap(_ annotations: [ARAnnotation])
{
var mapAnnotations: [MKPointAnnotation] = []
for annotation in annotations
{
if let coordinate = annotation.location?.coordinate
{
let mapAnnotation = MKPointAnnotation()
mapAnnotation.coordinate = coordinate
let text = String(format: "%#, AZ: %.0f, VL: %i, %.0fm", annotation.title != nil ? annotation.title! : "", annotation.azimuth, annotation.verticalLevel, annotation.distanceFromUser)
mapAnnotation.title = text
mapAnnotations.append(mapAnnotation)
}
}
mapView.addAnnotations(mapAnnotations)
mapView.showAnnotations(mapAnnotations, animated: false)
}
open func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)
{
heading = newHeading.trueHeading
if(!self.interactionInProgress && CLLocationCoordinate2DIsValid(mapView.centerCoordinate))
{
let camera = mapView.camera.copy() as! MKMapCamera
camera.heading = CLLocationDirection(heading);
self.mapView.setCamera(camera, animated: false)
}
}
open func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool)
{
self.interactionInProgress = true
}
open func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool)
{
self.interactionInProgress = false
}
}

you have to change its color in MKMapViewDelegate delegate method
#IBOutlet weak var customMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let anoot = MKPointAnnotation()
anoot.coordinate = CLLocationCoordinate2D.init(latitude: lat, longitude: lng)
customMap.addAnnotation(anoot)
customMap.delegate = self
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
annotationView.pinTintColor = UIColor.green
return annotationView
}
you can do it in your code like this
class ViewController: UIViewController {
var locationManager = CLLocationManager()
#IBOutlet weak var yourMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
yourMap.delegate = self
let anoot = MKPointAnnotation()
anoot.coordinate = CLLocationCoordinate2D.init(latitude: 23.0225, longitude: 72.5714)
yourMap.addAnnotation(anoot)
yourMap.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
locationManager.requestWhenInUseAuthorization()
}
}
extension ViewController: CLLocationManagerDelegate, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
annotationView.pinTintColor = UIColor.green
return annotationView
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.count > 0 {
let location = locations.last!
print("Accuracy: \(location.horizontalAccuracy)")
if location.horizontalAccuracy < 100 {
manager.stopUpdatingLocation()
let span = MKCoordinateSpan(latitudeDelta: 0.014, longitudeDelta: 0.014)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
yourMap.region = region
// let location = CLLocation(latitude: latitude, longitude: longitude)
// let place = Place(location: location, reference: reference, name: name, address: address)
// self.places.append(place)
//
// let annotation = MyHome(location: place.location!.coordinate, title: place.placeName)
//
// DispatchQueue.main.async {
//
// self.mapView.addAnnotation(annotation)
// }
}
}
}
}

Related

MKLocalSearch (search.start)always goes in the error flow. (SWIFT)

I've been trying to learn swift for the past few days and just started my own project! As part of the project I wanted to show nearby cocktail bars on a map, I was able to find some nice info online and have been able to show a map with my current location. I also found info on how to find nearby locations: https://developer.apple.com/documentation/mapkit/mklocalsearch/request
Unfortunately this last one never seems to work, it just goes out of the function and does not return any locations, could anyone help me further? Below is the code of my viewcontroller with the function getNearbyLandmarks which doesn't work as intended.
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet var mapView: MKMapView!
let manager = CLLocationManager()
private var landmarks: [Landmark] = [Landmark]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
manager.stopUpdatingLocation()
render(location)
}
}
func render(_ location: CLLocation){
let coordinate = CLLocationCoordinate2D(latitude: location.coordinate.latitude,
longitude: location.coordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.01,
longitudeDelta: 0.01)
let region = MKCoordinateRegion(center: coordinate,
span: span)
mapView.delegate = self
mapView.setRegion(region,
animated: true)
let pin = MKPointAnnotation()
pin.coordinate = coordinate
pin.title = "Current location"
mapView.addAnnotation(pin)
self.getNearByLandmarks()
updateAnnotations(from: mapView)
}
func mapView(_ mapViewIcon: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annotationView = mapViewIcon.dequeueReusableAnnotationView(withIdentifier: "custom")
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation,
reuseIdentifier: "custom")
annotationView?.canShowCallout = true
}else{
annotationView?.annotation = annotation
}
annotationView?.image = UIImage(named: "User")
return annotationView
}
private func getNearByLandmarks(){
let request = MKLocalSearch.Request()
request.naturalLanguageQuery = "coffee"
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.start{(response, error) in
if let response = response {
let mapItems = response.mapItems
self.landmarks = mapItems.map{
Landmark(placemark: $0.placemark)
}
}
}
}
private func updateAnnotations(from mapView: MKMapView){
let annotations = self.landmarks.map(LandmarkAnnotation.init)
mapView.addAnnotations(annotations)
}
}
You call getNearByLandmarks, and then immediately try to update the annotations:
self.getNearByLandmarks()
updateAnnotations(from: mapView)
but getNearByLandmarks is asynchronous, and takes some time to complete. You need to update the annotations whenever private var landmarks changes, one way is to update it in all the places that set that, like where you say
self.landmarks = mapItems.map{
Landmark(placemark: $0.placemark)
}
note you don't call updateAnnotations(from: mapView) there.
Or you could add a didSet property observer to landmarks itself so that updateAnnotations is called whenever it changes.

How to make the annotation appear on the Apple map via Swift?

So basically, I'm calling a Rest API to get all Bus Stops location, then put annotation of all bus stops within 5km from my current location on the map when a button is called. However, it is just not displaying, I can't seem to figure out the problem.
import UIKit
import MapKit
class MapKitViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var GPSButton: UIButton!
var stopSearchResults: [Value] = []
var Annotations: [BusStopAnnotation] = []
let queryServices = QueryService()
let locationManager:CLLocationManager = CLLocationManager()
#IBOutlet weak var mapView: MKMapView!
var currentLocation: CLLocationCoordinate2D?
var counter: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.isNetworkActivityIndicatorVisible = true
queryServices.GetAllBusStops(){
result in
UIApplication.shared.isNetworkActivityIndicatorVisible = false
if let result = result {
self.stopSearchResults = result.value
}
}
configureLocationService()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func configureLocationService() {
locationManager.delegate = self
let status = CLLocationManager.authorizationStatus()
if status == .notDetermined {
locationManager.requestAlwaysAuthorization()
} else if status == .authorizedAlways || status == .authorizedWhenInUse {
beginLocationUpdate(locationManager: locationManager)
}
}
private func beginLocationUpdate(locationManager: CLLocationManager) {
mapView.showsUserLocation = true
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
private func zoomToLatestLocation(with coordinate: CLLocationCoordinate2D) {
let zoomRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: 1000, longitudinalMeters: 1000)
mapView.setRegion(zoomRegion, animated: true)
}
#IBAction func GPSTrack(_ sender: Any) {
InputAllAnnotation(busStops: stopSearchResults)
print("Searching for nearby bus stops")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Did get latest location")
guard let latestLocation = locations.first else { return }
if currentLocation == nil {
zoomToLatestLocation(with: latestLocation.coordinate)
}
currentLocation = latestLocation.coordinate
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("The status changed")
if status == .authorizedAlways || status == .authorizedWhenInUse {
beginLocationUpdate(locationManager: manager)
}
}
func InputAllAnnotation(busStops: [Value]) {
for busStop in busStops{
let busStopObj = BusStopAnnotation(value: busStop)
Annotations.append(busStopObj)
let distance = busStop.GetDistance(latitude: Double(currentLocation?.latitude ?? 0), longitude: Double(currentLocation?.longitude ?? 0))
if distance < 5000 {
mapView.addAnnotation(busStopObj)
}
}
}
}
extension MapKitViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let busStopAnnotation = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) as?
MKMarkerAnnotationView {
busStopAnnotation.animatesWhenAdded = true
busStopAnnotation.titleVisibility = .adaptive
busStopAnnotation.canShowCallout = true
return busStopAnnotation
}
return nil
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
print("The annotation was selected: \(String(describing: view.annotation?.title))")
}
}
final class BusStopAnnotation: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
var busStopCode: String?
init(value : Value) {
self.coordinate = value.GetLocationCoordinate2D()
self.title = value.roadName
self.subtitle = value.description
self.busStopCode = value.busStopCode
}
init(coordinate: CLLocationCoordinate2D, roadName: String?, description: String?, busStopCode: String?) {
self.coordinate = coordinate
self.title = roadName
self.subtitle = description
self.busStopCode = busStopCode
}
var region: MKCoordinateRegion {
let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
return MKCoordinateRegion(center: coordinate, span: span)
}
}
You may need
self.mapView.delegate = self
import:
import UIKit
import MapKit
set class
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
outlet your map
#IBOutlet weak var map: MKMapView!
Code:
let customPin : CLLocationCoordinate2D = CLLocationCoordinate2DMake(Latitude, Longitude)
let objectAnnotation = MKPointAnnotation()
objectAnnotation.coordinate = customPin
objectAnnotation.title = "Here's your custom PIN"
self.map.addAnnotation(objectAnnotation)
extra:
to set the camera near the PIN
let theSpan:MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.009, longitudeDelta: 0.009)
let pointLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(Latitude, Longitude)
let region:MKCoordinateRegion = MKCoordinateRegion(center: pointLocation, span: theSpan)
self.map.setRegion(region, animated: true)
move values depending how close/far you want the camera
let theSpan:MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: HERE, longitudeDelta: HERE)

MapKit zoom to user current location

I am trying to simply show user's location on the map, but I need to when app launches, the map should zoom to current location ,but I don't know why map doesn't zoom at all and it's like this :
Here is the code :
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
mapView.showsUserLocation = true
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
DispatchQueue.main.async {
self.locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let location = locations.last as! CLLocation
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
var region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
region.center = mapView.userLocation.coordinate
mapView.setRegion(region, animated: true)
}
I faced similar issue and wasted 4 days thinking whats going wrong. Finally resolved with creating these lines of code in viewDidLoad Method :
//Zoom to user location
let noLocation = CLLocationCoordinate2D()
let viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 200, 200)
mapView.setRegion(viewRegion, animated: false)
mapView.showsUserLocation = true
In ViewDidLoad Method add these new changes code :
override func viewDidLoad() {
super.viewDidLoad()
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Check for Location Services
if (CLLocationManager.locationServicesEnabled()) {
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
}
//Zoom to user location
if let userLocation = locationManager.location?.coordinate {
let viewRegion = MKCoordinateRegionMakeWithDistance(userLocation, 200, 200)
mapView.setRegion(viewRegion, animated: false)
}
self.locationManager = locationManager
DispatchQueue.main.async {
self.locationManager.startUpdatingLocation()
}
}
Hope this helps to resolve your issue. Feel free to post comment if any further issue. Thanks
Here's another approach for Swift 3, XCode 8.2. First, write out a helper function:
let homeLocation = CLLocation(latitude: 37.6213, longitude: -122.3790)
let regionRadius: CLLocationDistance = 200
func centerMapOnLocation(location: CLLocation)
{
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: true)
}
Then, call in in viewDidLoad()
mapView.showsUserLocation = true
centerMapOnLocation(location: homeLocation)
This will start the app with the location specified in the variable zoomed in.
In Swift 4.2 there has been changes with this code. Here is how it works now:
import UIKit
import MapKit
import CoreLocation
class MapVC: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var locationManager = CLLocationManager()
let authorizationStatus = CLLocationManager.authorizationStatus()
let regionRadius: Double = 1000
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager.delegate = self
configureLocationServices()
}
func centerMapOnUserLocation() {
guard let coordinate = locationManager.location?.coordinate else {return}
let coordinateRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: regionRadius, longitudinalMeters: regionRadius)
mapView.setRegion(coordinateRegion, animated: true)
}
func configureLocationServices() {
if authorizationStatus == .notDetermined {
locationManager.requestAlwaysAuthorization()
} else {
return
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
centerMapOnUserLocation()
}
}
Code:
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapview: MKMapView!
let locationmanager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
mapview.mapType = MKMapType.standard
let location = CLLocationCoordinate2DMake(22.4651, 70.0771)
let span = MKCoordinateSpanMake(0.5, 0.5)
let region = MKCoordinateRegionMake(location, span)
mapview.setRegion(region, animated: true)
let annonation = MKPointAnnotation()
annonation.coordinate = location
annonation.title = "Chandi Bazar"
annonation.subtitle = "Jamnagar"
//
mapview.addAnnotation(annonation)
self.locationmanager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled()
{
locationmanager.delegate = self
locationmanager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationmanager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
locationmanager.stopUpdatingLocation()
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
if (annotation is MKUserLocation)
{
return nil
}
let annotationidentifier = "Annotationidentifier"
var annotationview:MKAnnotationView
annotationview = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationidentifier)
let btn = UIButton(type: .detailDisclosure)
btn.addTarget(self, action: #selector(ViewController.hirenagravat(sender:)), for: .touchUpInside)
annotationview.rightCalloutAccessoryView = btn
annotationview.image = UIImage(named: "images (4).jpeg")
annotationview.canShowCallout = true
return annotationview
}
func hirenagravat(sender:UIButton)
{
let fvc = storyboard?.instantiateViewController(withIdentifier: "secondViewController") as? secondViewController
self.navigationController?.pushViewController(fvc!, animated: true)
}
In swift 4.1. To change the Zoom level you need to change the span value i.e MKCoordinateSpan(latitudeDelta: 0.95, longitudeDelta: 0.95)
let lat = "33.847105"
let long = "-118.2673272"
let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: Double(lat)!, longitude: Double(long)!), span: MKCoordinateSpan(latitudeDelta: 0.95, longitudeDelta: 0.95))
DispatchQueue.main.async {
self.mapView.setRegion(region, animated: true)
}
Swift 5.0
let span = MKCoordinateSpan.init(latitudeDelta: 0.01, longitudeDelta:
0.01)
let coordinate = CLLocationCoordinate2D.init(latitude: 21.282778, longitude: -157.829444) // provide you lat and long
let region = MKCoordinateRegion.init(center: coordinate, span: span)
mapView.setRegion(region, animated: true)
when you set region -> you cannot zoom the map anymore. below to fix that
func yourFuncName() {
//this is global var
regionHasBeenCentered = false
if !self.regionHasBeenCentered {
let span: MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
let userLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(_cllocationOfUserCurrentLocation!.coordinate.latitude, _cllocationOfUserCurrentLocation!.coordinate.longitude)
let region: MKCoordinateRegion = MKCoordinateRegionMake(userLocation, span)
self.mapView.setRegion(region, animated: true)
self.regionHasBeenCentered = true
}
self.mapView.showsUserLocation = true
}
Try with MKMapViewDelegate func:
var isInitiallyZoomedToUserLocation: Bool = false
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
if !isInitiallyZoomedToUserLocation {
isInitiallyZoomedToUserLocation = true
mapView.showAnnotations([userLocation], animated: true)
}
}
func animateToUserLocation() {
if let annoation = mapView.annotations.filter ({ $0 is MKUserLocation }).first {
let coordinate = annoation.coordinate
let viewRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: 200, longitudinalMeters: 200)
mapView.setRegion(viewRegion, animated: true)
}
}

make pin draggable and long click

I've been trying for hours to make the pin draggable in MapKit, but it seems that the pin is so stubborn it didn't want to move.
this is my code:
import UIKit
import MapKit
protocol AddCoffeeDelegate {
func viewController(vc: AddCoffeeViewController, didAddCoffee coffee : Coffee! )
}
class AddCoffeeViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet var mapView: MKMapView!
#IBOutlet weak var coffeeName: UITextField!
#IBOutlet weak var coffeeRating: UITextField!
var coffee: Coffee?
var delegate: AddCoffeeDelegate?
////////////////////////////////////////////////////
var coreLocationManager = CLLocationManager()
var locationManager : LocationManager!
var savedLocation : CLLocation?
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKPointAnnotation {
let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myPin")
pinAnnotationView.pinTintColor = UIColor.redColor()
pinAnnotationView.draggable = true
pinAnnotationView.canShowCallout = false
pinAnnotationView.animatesDrop = true
return pinAnnotationView
}
return nil
}
func getLocation(){
locationManager.startUpdatingLocationWithCompletionHandler { (latitude, longitude, status, verboseMessage, error) -> () in
self.displayLocation(CLLocation(latitude: latitude, longitude: longitude))
}
}
func displayLocation(location: CLLocation){
mapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude), span: MKCoordinateSpanMake(0.05, 0.05)), animated: true)
let locationPinCoord = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let annotation = MKPointAnnotation()
annotation.title = "My Title"
annotation.subtitle = "My Subtitle"
annotation.coordinate = locationPinCoord
mapView.addAnnotation(annotation)
savedLocation = location
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status != CLAuthorizationStatus.NotDetermined || status != CLAuthorizationStatus.Denied || status != CLAuthorizationStatus.Restricted {
getLocation()
}
}
////////////////////////////////////////////////////
override func viewDidLoad() {
super.viewDidLoad()
coreLocationManager.delegate = self
locationManager = LocationManager.sharedInstance
let authorizationCode = CLLocationManager.authorizationStatus()
if authorizationCode == CLAuthorizationStatus.NotDetermined && coreLocationManager.respondsToSelector("requestAlwaysAuthorization") || coreLocationManager.respondsToSelector("requestWhenInUseAuthorization"){
if NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationAlwaysUsageDescription") != nil {
coreLocationManager.requestAlwaysAuthorization()
}else{
print("no desscription provided ")
}
}else{
getLocation()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func cancel(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func save(sender: AnyObject) {
var createdCoffee = Coffee()
createdCoffee.name = self.coffeeName.text!
createdCoffee.rating = Double(self.coffeeRating.text!)!
createdCoffee.place = savedLocation
self.coffee = createdCoffee
self.delegate?.viewController(self, didAddCoffee: self.coffee)
}
}
I have tried every related issue with mapkit in swift, but it seems that the pin won't drag itself.Where could the problem be? I have already set the title and implement the MKMapViewDelegate protocol, but still it wont drag.
Did you set the delegate of the mapview to the view controller either in code, or via the Storyboard?
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
...
}

Swift : MKAnnotation, implementation of mapView delegate to customize pin

I'm just trying to convert the red pins into purple ones.
Here is the FirstViewController.swift code :
import UIKit
import CoreLocation
import MapKit
class FirstViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var theMap: MKMapView!
var locationManager = CLLocationManager()
var userLocation = CLLocation()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
//The Pin
let pin1 = CLLocationCoordinate2D(
latitude: 48.89,
longitude: 2.6968
)
let thepoint = MKPointAnnotation()
thepoint.coordinate = pin1
thepoint.title = "the title"
thepoint.subtitle = "the subtitle"
theMap.addAnnotation(thepoint)
}
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
pinView!.pinColor = .Purple
}
else {
pinView!.annotation = annotation
}
return pinView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("error")
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
userLocation = locations[0] as! CLLocation
locationManager.stopUpdatingLocation()
let location = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: location, span: span)
theMap.setRegion(region, animated: false)
}
}
I know that I'm doing wrong with the implementation of the mapView function.
Is there anyone to help me ?
Thanks

Resources