So I have a map view(mapkit based) and a slider in my storyboard. As the user slides, map zooms in or out based on their action. How do I implement that? I think that might have something to do with longitudeDelta and latitudeDelta.
Please help me.
import UIKit
import MapKit
import CoreLocation
class ConfigureViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapkitView: MKMapView!
#IBOutlet weak var travelRadius: UILabel!
#IBAction func button(sender: AnyObject) {
}
#IBAction func sliderChanged(sender: AnyObject) {
let sliderValue = lrintf(sender.value)
travelRadius.text = "\(sliderValue) mi."
let delta = Double(self.sliderChanged(sender.value))
var currentRegion = self.mapkitView.region
currentRegion.span = MKCoordinateSpan(latitudeDelta: delta, longitudeDelta: delta)
self.mapkitView.region = currentRegion
}
let locationManager = CLLocationManager()
#IBOutlet weak var mapKitView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapKitView.showsUserLocation = true
// Do any additional setup after loading the view.
}
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: 1.5,
longitudeDelta: 1.5))
self.mapKitView.setRegion(region, animated: false)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print ("Errors:" + error.localizedDescription)
}
}
Screenshot of my storyboard
You set the zoom via the region property of the mapView. It defines both the center point of the map and the span (i.e. zoom level)
Edit
Do yourself a favor and define a separate IBOutlet for the slider. It turns out that your slider is measured in miles, but the span is measured in degrees latitude and longitude. How long 1 degree of latitude/longitude is in terms of miles vary depend on your location on Earth. Wikipedia has some discussion on latitude and longitude. Assuming you are on the equator, the conversion is 69 miles per degree of both.
(Remember to connect the outlets)
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var slider: UISlider!
#IBOutlet weak var travelRadius: UILabel!
#IBOutlet weak var currentLocationLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
sliderChanged(self) // Set the correct zoom according to the slider initial value
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func sliderChanged(sender: AnyObject) {
let miles = Double(self.slider.value)
let delta = miles / 69.0
var currentRegion = self.mapView.region
currentRegion.span = MKCoordinateSpan(latitudeDelta: delta, longitudeDelta: delta)
self.mapView.region = currentRegion
travelRadius.text = "\(Int(round(miles))) miles"
let (lat, long) = (currentRegion.center.latitude, currentRegion.center.longitude)
currentLocationLabel.text = "Current location: \(lat), \(long))"
}
}
Related
I wish to save latitude and longitude coordinates in two labels on a second view controller but I am having trouble getting it to work.
Here is my code:
First View Controller:
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, 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()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
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: true)
}
}
Second View Controller:
import UIKit
class AddSightingViewController: UIViewController {
var getCoordinates: ViewController!
#IBOutlet weak var latitudeLabel: UILabel!
#IBOutlet weak var longitudeLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
latitudeLabel.text = "\(getCoordinates.locationManager.location?.coordinate.latitude)"
longitudeLabel.text = "\(getCoordinates.locationManager.location?.coordinate.longitude)"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
when you push VC
objAddSightVC.location = CLLocationCoordinate2D(latitude: your_lat, longitude: your_long)
in AddSightingViewController
var location : CLLocationCoordinate2D!
and
latitudeLabel.text = String(describing: location.latitude)
longitudeLabel.text = String(describing: location.longitude)
on storyboard initiate or push VC
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
let addSightingViewController = AddSightingViewController(location :coordinate)
in AddSightingViewController declare property location with init constructor
class AddSightingViewController: UIViewController {
let location:LLocationCoordinate2D
init(location:LLocationCoordinate2D!){
self.location = location
}
override func viewDidLoad() {
super.viewDidLoad()
latitudeLabel.text = "\(location?.coordinate.latitude)"
longitudeLabel.text = "\(location?.coordinate.longitude)"
}
}
I searched on everywhere, but i could not find it. I want to below action.
When I touch the annotation on the map, I want to change text on the view.
I tried below code but this does not work. I simply change text on the screen when annotation pin clicked.
private func mapView(mapView: MKMapView, didSelect view: MKAnnotationView{
hastane_adi_text.text = "HAstane"
}
You can see my "ViewControllerClass" below.
import UIKit
import MapKit
import CoreLocation
class HospitalControlloer: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate{
#IBOutlet weak var hastane_adi_text: UILabel!
#IBOutlet weak var map: MKMapView!
#IBOutlet weak var randevu_al_button: UIButton!
#IBOutlet weak var hizala_button: UIButton!
let locationMenager = CLLocationManager()
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
randevu_al_button.layer.cornerRadius = 10;
hizala_button.layer.cornerRadius = 10;
let locationS:CLLocationCoordinate2D = CLLocationCoordinate2DMake(41.169425, 29.056801)
let sd = MKPointAnnotation()
sd.coordinate = locationS
sd.title = "Sarıyer Merkez Hastane"
let locationS2:CLLocationCoordinate2D = CLLocationCoordinate2DMake(41.097076, 29.05341)
let sd2 = MKPointAnnotation()
sd2.coordinate = locationS2
sd2.title = "Sarıyer Baltalimanı Hastane"
map.addAnnotation(sd)
map.addAnnotation(sd2)
self.locationMenager.delegate = self
self.locationMenager.desiredAccuracy = kCLLocationAccuracyBest
self.locationMenager.requestWhenInUseAuthorization()
self.locationMenager.startUpdatingLocation()
self.map.showsUserLocation = true
// Do any additional setup after loading the view.
}
private func mapView(mapView: MKMapView, didSelect view: MKAnnotationView){
hastane_adi_text.text = "HAstane"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func locate_button(_ sender: Any) {
locationMenager.requestLocation()
}
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.1, longitudeDelta: 0.1) )
self.map.setRegion(region, animated: true)
self.locationMenager.stopUpdatingLocation()
}
I think you should change delegate func to
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
hastane_adi_text.text = "HAstane"
}
and add map.delegate = self at viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
.....
}
Hello you need to implement this method func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) and add your viewController as map delegate self.map.delegate = self
I hope this helps you
I have many different buttons like UIStepper and DatePicker and a MapView. Can anyone help me get my whole view controller and the button working. I have been getting an error about SIGABRT. It say's "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Field_Service_Report.AddController hoursStepper:]: unrecognized selector sent to instance 0x7fb5d7c8d010'"
This is my View Controller code :
import UIKit
import MapKit
import CoreLocation
class AddController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var hoursStepperResult: UILabel!
#IBOutlet weak var hoursStepper: UIStepper!
#IBOutlet weak var minutesStepperResult: UILabel!
#IBOutlet weak var minutesStepper: UIStepper!
#IBOutlet weak var currentLocationLabel: UILabel!
#IBOutlet weak var dateOfReport: UIDatePicker!
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Start Map Contents
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
// End Map Contents
}
// Start Stepper Contents
#IBAction func hoursStepperAction(_ sender: UIStepper) {
hoursStepperResult.text = String(Int(sender.value))
}
#IBAction func minutesStepperAction(_ sender: UIStepper) {
minutesStepperResult.text = String(Int(sender.value))
}
// End Stepper Contents
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Here is the new code its giving me 3 erroe because im trying to get the text and numbers from another ViewController to print out in this VC.
#IBAction func doneACButton(_ sender: AnyObject) {
let newVC = storyboard?.instantiateViewController(withIdentifier: "ResultController") as! ResultController
newVC.intPassed = hoursIntProvided
newVC.intPassed = minutesIntProvided
newVC.stringPassed = resultedHours.text!
}
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: 1, longitudeDelta: 1))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Errors: " + error.localizedDescription)
}
// MARK: - Navigation
}
Notice the colon right here in the method signature:
-[Field_Service_Report.AddController hoursStepper:]
^
This is the signature of a method that takes a parameter, not the signature of an accessor. Are you sure you didn't misspell a selector name somewhere or leave something accidentally connected in IB that should have been removed? (Perhaps if you renamed a method and forgot to redo the action connection?)
hey all i am brand new into coding iOS apps, and find it rather enjoyable so far..
I am having an issue assigning lat and lng to a text field. I have been following along in a tutorial but it crapped out and most examples i have found are in objective C and not swift.. and the ones in swift aren't all the best..
my ViewController is below:
import UIKit
import MapKit
class LocationVC: UIViewController, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
#IBOutlet weak var latField: UITextField!
#IBOutlet weak var lngField: UITextField!
#IBOutlet weak var locateBtn: UIButton!
#IBOutlet weak var saveBtn: UIButton!
let regionRadius: CLLocationDistance = 500
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
override func viewDidAppear(animated: Bool) {
locationAuthStatus()
}
func locationAuthStatus() {
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
map.showsUserLocation = true
} else {
locationManager.requestWhenInUseAuthorization()
}
}
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 1, regionRadius * 1)
map.setRegion(coordinateRegion, animated: true)
}
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
if let loc = userLocation.location {
centerMapOnLocation(loc)
}
let latField = location.longitude
let lngField = location.latitude
}
}
So far the map is moving, works on my device but I have no idea how to get the coords to appear..
Please forgive me if this is a noob question, but I just cant get this damn thing to go..
Replace your mapView(_ :,didUpdatedUserLocation:) with this...
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
if let loc = userLocation.location
{
centerMapOnLocation(loc)
self.latField.text = "\(loc.coordinate.latitude)"
self.lngField.text = "\(loc.coordinate.longitude)"
}
}
Note: If you only need show the lat/lng could be a better idea to use an UILabel instead of UITextFiel
Hi here is my code so far
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet var map: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var userLocation:CLLocation = locations[0] as! CLLocation
var latitude = userLocation.coordinate.latitude
var longitude = userLocation.coordinate.longitude
var latDelta:CLLocationDegrees = 0.05
var lonDelta:CLLocationDegrees = 0.05
var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
self.map.setRegion(region, animated: false)
println(latitude)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I would like to access the info in the locationManager function in a second view controller showing the latitude, longitude, course and speed. Am a newbie so any help would be great. cheers
Move your variables you want to pass to the second VC from local to class-scope:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet var map: MKMapView!
var locationManager = CLLocationManager()
var longitude:CLLocationDegrees!
var latitude:CLLocationDegrees!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
Create your Target UIViewController with variables to hold the passed values:
import UIKit
import MapKit
import CoreLocation
class MyDestinationViewController: UIViewController {
var longitude:CLLocationDegrees!
var latitude:CLLocationDegrees!
override func viewDidLoad() {
super.viewDidLoad()
}
}
Add the prepareForSegue method to your viewcontroller from which you want to send the data:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destinationVC = segue.destinationViewController as! MyDestinationViewController
destinationVC.latitude = latitude
destinationVC.longitude = longitude
}
If you do not want to use a segue, you can just instanciate the targetViewController and pass the variables, before presenting the VC.