when I perform my segue, the location is still updated in the next VC. I tried to put the startUpdatingLocation() into an other function than the super view, but nothing changed. Do you have any ideas what i can do? Grüße aus Mannheim
import UIKit
import MapKit
import CoreLocation
class uploadPrepare: UIViewController, UITextViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var weiterButton: UIButton!
let locationPrepare = CLLocationManager()
var regionPrepare: MKCoordinateRegion!
override func viewDidLoad() {
super.viewDidLoad()
locationPrepare.delegate = self
locationPrepare.desiredAccuracy = kCLLocationAccuracyBest
locationPrepare.requestWhenInUseAuthorization()
locationPrepare.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func weiterButtonTapped(_ sender: UIButton){
self.locationPrepare.stopUpdatingLocation()
self.performSegue(withIdentifier: "goToMapCheck", sender: self)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locationPrepare = locations[0]
let myLocationPrepare:CLLocationCoordinate2D = CLLocationCoordinate2DMake(locationPrepare.coordinate.latitude,locationPrepare.coordinate.longitude)
let span: MKCoordinateSpan = MKCoordinateSpanMake(0.0005,0.0005)
regionPrepare = MKCoordinateRegionMake(myLocationPrepare,span)
print("\(locationPrepare.coordinate.latitude)")
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
let uploadInterfaceGoing = segue.destination as! mapCheck
uploadInterfaceGoing.regionReceived = regionPrepare
}
}
Related
Im using Xcode 8 and swift 3
I created a new project selecting new "Tabbed Application" when i created it. It provided two UIViewControllers embedded in one tab bar controller. I'm trying to pass two variables between the view controllers.
The problem is that the prepare for segue function is never called. I added a print statement in it that never prints. I added the prepare function in both view controllers and can tab back and forth with no prints.
Some code:
import UIKit
import MapKit
import CoreLocation
class FirstViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate{
#IBOutlet weak var mapView: MKMapView!
var locationManager:CLLocationManager?
var currentLocation:CLLocation?
var destPin: MapPin?
var isTracking: Bool? = false
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.startUpdatingLocation()
locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager?.requestAlwaysAuthorization()
updateTracking()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.currentLocation = locations[0]
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func getMapView()-> MKMapView{
return mapView
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if(self.isTracking!){
print("Istracking bool is true")
}
else{
print("Istracking bool is false")
}
updateTracking()
locationManager?.stopUpdatingLocation()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("Preparing")
let barViewControllers = segue.destination as! UITabBarController
let destinationViewController = barViewControllers.viewControllers![1] as! FirstViewController
destinationViewController.destPin = self.destPin
destinationViewController.isTracking = self.isTracking
}
}
The contents of the prepare function may very well be wrong as well but without the function even being called it hardly matters. The other view controller is also embedded in the tab bar controller and also has a prepare function that does not execute.
If you'd like, its in this github repo
It is easy to do:
The result:
For example, there are FirstViewController and SecondViewController embeded in tabViewController:
In your firstViewController.swift:
import UIKit
class FirstViewController: UIViewController {
var vc1_variable:String = "first vc's variable."
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In your secondViewController.swift:
import UIKit
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let first_vc:FirstViewController = self.tabBarController?.viewControllers![0] as! FirstViewController
print("\(first_vc.vc1_variable)")
}
}
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?)
I'm new to Swift and iOS development. I'm trying to load a secondary view controller as an overlay over a mapView, and when I try to do it I run into the error listed in the title. I'm stumped.
My code is as follows:
// mainMapViewController.swift
import UIKit
import MapKit
import CoreLocation
var events = [Event]()
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UIGestureRecognizerDelegate {
#IBOutlet weak var mapView: MKMapView!
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let locationManager = CLLocationManager()
#IBAction func addEvent(mylongpress: UIGestureRecognizer) {
if mylongpress.state == UIGestureRecognizerState.Began {
let touchpoint = mylongpress.locationInView(mapView)
let newcoord = mapView.convertPoint(touchpoint, toCoordinateFromView: mapView)
let pin = MKPointAnnotation()
pin.coordinate = newcoord
let eventcreatevc = mainStoryBoard.instantiateViewControllerWithIdentifier("EventCreate") as! EventCreate
eventcreatevc.modalPresentationStyle = .OverCurrentContext
self.presentViewController(eventcreatevc, animated: true, completion: nil)
//events.last!.annotation = pin
//events.last!.annotation.title = events.last!.eventName
//pin.title = events.last!.annotation.title
if events.isEmpty {
pin.title = "this is a test"
}
self.mapView.addAnnotation(pin)
print("added pin to map")
}
}
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.07, longitudeDelta: 0.07))
self.mapView.setRegion(region, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
let longpress = UILongPressGestureRecognizer(target: self, action: "addEvent:")
mapView.addGestureRecognizer(longpress)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "EventCreate" {
var eventcreatevc = segue.destinationViewController as! EventCreate
}
}
override func viewWillAppear(animated: Bool) {
if events.isEmpty {
return
}
else {
for listofevent in events {
let pin = listofevent.annotation
self.mapView.addAnnotation(pin)
}
return
}
}
}
and
// EventCreate.swift
import UIKit
import MapKit
import CoreLocation
class EventCreate: UIViewController, UITextFieldDelegate, MKMapViewDelegate, UIGestureRecognizerDelegate {
// MARK: Properties
var name: String = ""
var loc: String = ""
var cost: Int = 0
var date: String = ""
var annot: MKPointAnnotation = MKPointAnnotation()
#IBOutlet weak var datePicker: UIDatePicker!
#IBOutlet weak var costSlider: UISlider!
#IBOutlet weak var locationTextField: UITextField!
#IBOutlet weak var locationLabel: UILabel!
#IBOutlet weak var nameTextField: UITextField!
#IBOutlet weak var costLabel: UILabel!
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var eventNameLabel: UILabel!
#IBOutlet weak var createButton: UIButton!
// MARK: UITextFieldDelegate
func textFieldDidBeginEditing(textField: UITextField) {
createButton.enabled = false
}
func checkValidTextEntry(textField: UITextField) {
let text = textField.text ?? ""
createButton.enabled = !text.isEmpty
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
// hides the keyboard
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
if textField == nameTextField {
checkValidTextEntry(textField)
name = textField.text!
}
else if textField == locationTextField {
loc = textField.text!
}
}
func setAnnotation(annot: MKPointAnnotation) {
self.annot = annot
}
// MARK: Initialization
override func viewDidLoad() {
super.viewDidLoad()
nameTextField.delegate = self
locationTextField.delegate = self
checkValidTextEntry(nameTextField)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: Actions
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if createButton === sender {
let event = Event(eventName: name, location: loc, cost: cost, date: date, annotation: annot)
events.append(event!)
}
}
}
Any help would be greatly appreciated!
I can add Annotation on MapView using "first" button, but I would like to add a new option which enables the removing of the annotation using the "second" button. I have no problem with adding annotation, but I cannot remove it from the map view. Can somebody help me in it?
Here is my code:
class ViewController: UIViewController {
#IBOutlet weak var mapViewOutlet: MKMapView!
var lm = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.lm.requestAlwaysAuthorization()
mapViewOutlet.showsUserLocation = true
mapViewOutlet.userTrackingMode = MKUserTrackingMode.Follow
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// HERE IS FUNCTION ADDANNOTATION
#IBAction func tagMyCar(sender: UIButton) {
let coordinate = lm.location?.coordinate
let CarCoordinates = CarAdnotaion(coordinate: coordinate!)
mapViewOutlet.addAnnotation(CarCoordinates)
let region = CLCircularRegion(center: coordinate!, radius: 5, identifier: "My Car")
region.notifyOnEntry = true
region.notifyOnExit = true
lm.startMonitoringForRegion(region)
}
// HERE IS FUNCTION REMOVEANNOTATION
#IBAction func removeAnnotationfromMap(sender: AnyObject) {
let region = CLCircularRegion(center: (lm.location?.coordinate)!, radius: 5, identifier: "Mój samochód")
self.mapViewOutlet.removeAnnotation(CarAdnotaion(coordinate: (lm.location?.coordinate)!))
lm.stopMonitoringForRegion(region)
}
}
I think the problem is here:
self.mapViewOutlet.removeAnnotation(CarAdnotaion(coordinate: (lm.location?.coordinate)!))
You are removing annotation that you just created in this very statemen. Instead, move let CarCoordinates up (and give it more sensible name and lowercase letter in the beginning). Then call removeAnnotation on that object.
I have a solution of my problem. It works!
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController {
#IBOutlet weak var mapViewOutlet: MKMapView!
let lm = CLLocationManager()
var carAnnotation: CarAnnotationOnMap?
var region: CLCircularRegion?
override func viewDidLoad() {
super.viewDidLoad()
self.lm.requestAlwaysAuthorization()
mapViewOutlet.userTrackingMode = MKUserTrackingMode.Follow
mapViewOutlet.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// ADD ANNOTATION ON MAP
#IBAction func tagMyCar(sender: UIButton) {
let coordinates = lm.location?.coordinate
carAnnotation = CarAnnotationOnMap(coordinates: coordinates!)
region = CLCircularRegion(center: coordinates!, radius: 5, identifier: "My Zone")
region!.notifyOnEntry = true
region!.notifyOnExit = true
self.lm.startMonitoringForRegion(region!)
mapViewOutlet.addAnnotation(carAnnotation!)
}
// REMOVE ANNOTATION FROM MAP
#IBAction func removePinFromMyCar(sender: AnyObject) {
self.lm.stopMonitoringForRegion(region!)
mapViewOutlet.removeAnnotation(carAnnotation!)
}
}
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.