Adding Pins to Map using MapKit - Swift 3.0 - ios

New coder, trying to figure out how to use MapKit. The goal is to create a map that users can add pins to using their address. However, the step I am at now, I am having trouble figuring out how to add pins to the map at all.
How can I add a pin to the map? I have been struggling to figure out how to use annotations thus far.
That's what I'm hoping for help/direction with. Thanks!
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate
{
#IBOutlet weak var bigMap: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.bigMap.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
self.bigMap.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Errors " + error.localizedDescription)
}
}

They're called annotations in the MapKit and you should instantiate them like so:
let annotation = MKPointAnnotation()
then in the viewDidLoad() method just set the coordinates and add them to the map like:
annotation.coordinate = CLLocationCoordinate2D(latitude: 11.12, longitude: 12.11)
mapView.addAnnotation(annotation)
The numbers are your coordinates

The way that I learned how to do this is:
In the same function as viewDidLoad(), place the following lines of code:
let annotation = MKPointAnnotation()
annotation.title = "Your text here"
//You can also add a subtitle that displays under the annotation such as
annotation.subtitle = "One day I'll go here..."
annotation.coordinate = center
This is the only place I can see where you have a coordinate
if all else fails, just add the coordinate (search on Google if you
need to know how to create a coordinate) and set it equal to the
"annotation.coordinate" variable
map.addAnnotation(annotation)
Dassit!

Related

Getting location in swift 5

I realize there are lots of other pages that attempt to solve the challenge of getting user location using CLLocationManager() in ios swift but they don't work for me which is why I created this question. My code is below which I believe correctly implements the CLLocationManagerDelegate but the call to locationManager.startUpdatingLocation() never calls the locationManager function. This makes the Google Map simply open to a random position. I've simulated certain locations in the scheme and they work great like South Africa
example of Google Map with simulated location:
However, when I uncheck the simulation, the location is never found. Any advice or help would be appreciated. Not sure if this is a problem with my computer or code.
import UIKit
import GoogleMaps
class Map: UIViewController, CLLocationManagerDelegate {
var mapView: GMSMapView?
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: GMSCameraPosition.camera(withLatitude: 40.7, longitude: -74.0, zoom: 4.0))
view = mapView
if (CLLocationManager.locationServicesEnabled()){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let center = CLLocationCoordinate2D(latitude: locations.last!.coordinate.latitude, longitude: locations.last!.coordinate.longitude)
let camera = GMSCameraPosition.camera(withLatitude: center.latitude, longitude: center.longitude, zoom: 4.0);
self.mapView?.camera = camera
self.mapView?.isMyLocationEnabled = true
let marker = GMSMarker(position: center)
print("Latitude :\(center.latitude)")
print("Longitude :\(center.longitude)")
marker.map = self.mapView
marker.title = "Current Location"
locationManager.stopUpdatingLocation()
}
}

MapView that is zoomed in on the users current location in Xcode iOS Development

I've tried the following solutions:
Zoom in on User Location- Swift
Get User's Current Location / Coordinates
Determine User’s Current Location Example in Swift
But all I get is a map zoomed in on some other location, like San Francisco or somewhere in the middle east.
The top answer for solution3 looks like it shows how to print the users current location but it doesn't show how to use it with a map.
My ViewController.swift file
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last! as CLLocation
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
}
}

Custom map in Swift

I am currently developing an iOS application using location.
But I want to have a customized map to show user's location, not the default map given by MapKit.
A map like this for example :
Is it possible to achieve something like this in Swift 4.0 ?
Thanks a lot
You need to use MKTileOverlay - documentation is here...
As it says:
You use tile overlay objects to represent your own tile-based content
and to coordinate the display of that content in a map view. Your
tiles can supplement the underlying map content or replace it
completely.
(my emphasis)
This is how you can make a map show your live current location.
Full code:
import UIKit
import MapKit
//import CoreLocation
class ViewController: UIViewController, UIScrollViewDelegate ,CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet var map: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation: CLLocation = locations[0]
let latitude = userLocation.coordinate.latitude
let longitude = userLocation.coordinate.longitude
let latDelta: CLLocationDegrees = 0.05
let lonDelta: CLLocationDegrees = 0.05
let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)
let location = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let region = MKCoordinateRegion(center: location, span: span)
self.map.setRegion(region, animated: false)
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = "My current Location"
map.addAnnotation(annotation)
}
}
Note that you also have to add the permissions to the info.plist file
the permissions are:
Privacy - Location When In Use Usage Description
Privacy - Location Always Usage Description
Here is how you can give fixed location and a pin in a map view
import UIKit
import MapKit
class ViewController: UIViewController {
#IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let latitude : CLLocationDegrees = 86.44999
let longitude : CLLocationDegrees = 54.39
let latitudeDelta : CLLocationAccuracy = 0.05
let longituteDelta : CLLocationAccuracy = 0.05
let myLocation = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let mySpan = MKCoordinateSpanMake(latitudeDelta, longituteDelta)
let myRegion = MKCoordinateRegion(center: myLocation, span: mySpan)
myMap.setRegion(myRegion, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = myLocation
myMap.addAnnotation(annotation)
}
}

MKMapView seems to be nil?

I am new to Xcode and Swift and I am trying to simply make a map that shows the users current location and updates it. I have this so far:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
var mapp = MKMapView.self
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if (CLLocationManager.locationServicesEnabled())
{
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.map.showsUserLocation = true
}
else
{
print("Location services are not enabled")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func loadView() {
//let camera = GMSCameraPosition.camera(withLatitude: 36.2108, longitude: -81.6774, zoom: 15.0)
//let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
//mapView.isMyLocationEnabled = true
//view = mapView
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.002, longitudeDelta: 0.002))
self.map.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
{
print("Errors: " + error.localizedDescription)
}
}
I have made a MapView in the storyboard and CTRL dragged it to the file (thus the #IBOutlet weak var map: MKMapView!). However, when I plug my phone in and simulate the app it gives me a "unexpectedly found nil while unwrapping an optional value" and after some print statements i found that it happened whenever I referenced the map variable. Why is this? Thanks!
In the comments of the original post, Rob answered the question:
"
Remove the loadView method. That's used only when you are programmatically creating views. When using storyboards (or NIBs), you put your configuration code in viewDidLoad, not loadView. – Rob"
thank you Rob

Near given coordinates, print hello in Swift, MapKit and corelocation

I would like to know how to check if person is near some coordinates and then do something like say hello into console for testing. Right now I have already got user location and it is going to update every time person moves but how to know if he is near some coordinates or address? For example:
func sayHello(){
if mapView.userLocation.coordinate.latitude == 26{
print("Hello")
}
Code I've done already:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Errors: " + error.localizedDescription)
}
}
What I would do is every time you update the user's location, check the distance between your user's location and the address location(s) you have stored. If the user is within x meters, print "Hello".
Below is code I would use to get the distance between your user and the address. If you have an array of objects that contain your addresses and their coordinates you could loop through each address and print Hello for each address that is within x meters.
let userLocation:CLLocation = CLLocation(latitude: 10.000, longitude: 29.000)
let addressLocation:CLLocation = CLLocation(latitude: 15.000, longitude: 20.000)
let meters:CLLocationDistance = userLocation.distanceFromLocation(addressLocation)
Get the distance between two coordinates and match if its less than 5m than show print statement
CLLocation *locA = [[CLLocation alloc] initWithLatitude:lat1 longitude:long1];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:lat2 longitude:long2];
CLLocationDistance distance = [locA distanceFromLocation:locB];

Resources