regionDidChangeAnimated not working - ios

I am trying to run just a simple print function when the user moves the map around using gesture or search (moves the map in general) I've followed the apple ref guides and i get errors. Ive followed other stack overflow posts and other google search results. I don't know if it is because im using swift 2 or something in my code elsewhere that is contradicting. If somebody could help me that would be greatly appreciated. Here is my code
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate,
CLLocationManagerDelegate, UISearchBarDelegate
{
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var searchBar: UISearchBar!
let locationManager = CLLocationManager()
#IBAction func showSearchBar(sender: AnyObject) {
searchController = UISearchController(searchResultsController: nil)
searchController.hidesNavigationBarDuringPresentation = false
self.searchController.searchBar.delegate = self
presentViewController(searchController, animated: true, completion: nil)
}
#IBAction func locateMe(sender: AnyObject) {
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
}
#IBAction func photographer(sender: AnyObject) {
}
#IBAction func buyer(sender: AnyObject) {
}
var searchController:UISearchController!
var annotation:MKAnnotation!
var localSearchRequest:MKLocalSearchRequest!
var localSearch:MKLocalSearch!
var localSearchResponse:MKLocalSearchResponse!
var error:NSError!
var pointAnnotation:MKPointAnnotation!
var pinAnnotationView:MKPinAnnotationView!
override func viewDidLoad()
{
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool) {
hobo()
}
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Location Delegate Methods
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("Error: " + error.localizedDescription)
}
func searchBarSearchButtonClicked(searchBar: UISearchBar){
//1
searchBar.resignFirstResponder()
dismissViewControllerAnimated(true, completion: nil)
if self.mapView.annotations.count != 0{
annotation = self.mapView.annotations[0]
self.mapView.removeAnnotation(annotation)
}
//2
localSearchRequest = MKLocalSearchRequest()
localSearchRequest.naturalLanguageQuery = searchBar.text
localSearch = MKLocalSearch(request: localSearchRequest)
localSearch.startWithCompletionHandler { (localSearchResponse, error) -> Void in
if localSearchResponse == nil{
let alertController = UIAlertController(title: nil, message: "Place Not Found", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
return
}
//3
self.pointAnnotation = MKPointAnnotation()
self.pointAnnotation.title = searchBar.text
self.pointAnnotation.coordinate = CLLocationCoordinate2D(latitude: localSearchResponse!.boundingRegion.center.latitude, longitude: localSearchResponse!.boundingRegion.center.longitude)
self.pinAnnotationView = MKPinAnnotationView(annotation: self.pointAnnotation, reuseIdentifier: nil)
self.mapView.centerCoordinate = self.pointAnnotation.coordinate
self.mapView.addAnnotation(self.pinAnnotationView.annotation!)
}
}
func hobo(){
print("testing")
}
}

Make sure you set yourself as your map view's delegate in IB. Also, I'd try moving regionDidChangeAnimated out of viewDidLoad.

Related

Swift Manually Save Location Firebase

I want save manually location on map.I am tap on map and printing manually location. But my code(savemyadress) save current location. How should I edit code. Thanks
import UIKit
import MapKit
import Firebase
class MapViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var saveButton : UIBarButtonItem!
#IBOutlet var tapGesture: UITapGestureRecognizer!
let locationManager = CLLocationManager()
var ref: DatabaseReference!
var adres: Adresler!
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference()
}
func savemyadress(){
let sender = self.tapGesture
//if sender!.state == .ended{
let locationInView = sender!.location(in: mapView)
let tappedCoordinate = mapView.convert(locationInView, toCoordinateFrom: mapView)
let coordinateRegion = MKCoordinateRegion(center: tappedCoordinate, latitudinalMeters: 400, longitudinalMeters: 400)
mapView.setRegion(coordinateRegion, animated: true)
let userRef = self.ref.child("locations").child("Address")
let coordinate = tappedCoordinate
let adres = Adresler(latitude: coordinate.latitude , longitude: coordinate.longitude)
let Locations = userRef.childByAutoId()
let adresRef = Locations
adresRef.setValue(adres.toDictionary())
//}
}
#IBAction func tapGesture(_ sender: UITapGestureRecognizer) {
if sender.state == .ended{
let locationInView = sender.location(in: mapView)
let tappedCoordinate = mapView.convert(locationInView, toCoordinateFrom:mapView)
print(tappedCoordinate.latitude, tappedCoordinate.longitude)
}}}
extension MapViewController : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last! as CLLocation
let currentLocation = location.coordinate
let coordinateRegion = MKCoordinateRegion(center: currentLocation, latitudinalMeters: 400, longitudinalMeters: 400)
mapView.setRegion(coordinateRegion, animated: true)
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
guard let placemark = placemarks?.last else {
let errorString = error?.localizedDescription ?? "Unexpected Error"
return}
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("error:: (error)")}}
UPDATE
#IBAction func saveButton(_ sender: Any) {
let alert = UIAlertController(title: "Address", message: "Save address", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Save", style: .default, handler: { [self]action in
savemyadress()
_ = self.navigationController?.popViewController(animated: true)
}))
self.present(alert, animated: true)

How to add annotation based on current location when buttons is clicked? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I tried to add an annotation in my map when I click the button. I have written some codes but I am not getting any annotation based on my current location.
#IBAction func addPressed(_ sender: Any) {
guard let location = self.locationManager.location else {
return
}
let annotation = MKPointAnnotation()
annotation.title = "Flooded"
annotation.subtitle = "Reported on 12/10/2018 8:50 AM"
annotation.coordinate = location.coordinate
self.mapView.addAnnotation(annotation)
}
Add this to your view controller and also make sure to assign delegate to self for mapView in viewDidLoad()
Update: As dicsussed in comments, replace your complete view controller code with the code below.
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var add: UIButton!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager.delegate = self
checkLocationServices()
}
func setupLocationManager () {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func checkLocationServices() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorization()
} else {
}
}
func checkLocationAuthorization () {
switch CLLocationManager.authorizationStatus() {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
let alert = UIAlertController(title: "Location Services disabled", message: "Please enable Location Services in Settings", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
present(alert, animated: true, completion: nil)
return
case .denied:
let alert = UIAlertController(title: "Location Services disabled", message: "Please enable Location Services in Settings", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
present(alert, animated: true, completion: nil)
return
case .authorizedAlways:
break
case .authorizedWhenInUse:
mapView.showsUserLocation = true // this will bring the blue dot on map
centreZoomviewUserLocation()
locationManager.startUpdatingLocation()
#unknown default:
break
}
}
func centreZoomviewUserLocation () {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: 10000, longitudinalMeters: 10000)
mapView.setRegion(region, animated: true)
}
}
//MARK:- Button pressed
#IBAction func addPressed(_ sender: Any) {
guard let location = self.locationManager.location else {
return
}
let annotation = MKPointAnnotation()
annotation.title = "Flooded"
annotation.subtitle = "Reported on 12/10/2018 8:50 AM"
annotation.coordinate = location.coordinate
DispatchQueue.main.async {
self.mapView.addAnnotation(annotation)
}
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newPin = MKPointAnnotation()
guard let location = locations.last else { return }
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion.init(center: center, latitudinalMeters: 10000, longitudinalMeters: 10000)
mapView.setRegion(region, animated: true)
newPin.coordinate = location.coordinate
mapView.addAnnotation(newPin)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorization()
}
}
extension ViewController : MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard annotation is MKPointAnnotation else { return nil }
let identifier = "Annotation"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView!.canShowCallout = true
} else {
annotationView!.annotation = annotation
}
return annotationView
}
}

show location Swift3

I'm trying to show my current location on simulator but it displays another location
import UIKit
import MapKit
class DriverVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var myMap: MKMapView!
let locationManager = CLLocationManager()
var driverLocation : CLLocationCoordinate2D?
var userLocation : CLLocationCoordinate2D?
override func viewDidLoad() {
super.viewDidLoad()
intializeLocationManager()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locationManager.location?.coordinate {
print("location\(location)")
myMap.removeAnnotations(myMap.annotations)
driverLocation = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
let region = MKCoordinateRegion(center: driverLocation!, span: MKCoordinateSpanMake(0.07, 0.07))
myMap.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = driverLocation!
annotation.title = "driver location"
myMap.addAnnotation(annotation)
}
}
private func intializeLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
#IBAction func signOut(_ sender: UIBarButtonItem) {
if (AuthProvider.Instance.logOut()){
dismiss(animated: true, completion: nil)
}
else{
alertTheUser(title: "couldn't sign out", message: "try again")
}
}
#IBAction func answer(_ sender: UIButton) {
}
private func alertTheUser(title: String, message: String){
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(ok)
present(alert,animated: true, completion: nil)
}
}
I added Location when in usage description to Info.plist and the simulator debug location is non

How to setup a "Check-In" alert using Geofencing and CLCircularRegion?

I'm trying to set up an alert that once a user enters a specific location the alert pops up and allows users to "Check-in". After the user checks in the app then notifies an api endpoint that the user successfully checked in. This is my first time working with geofencing and corelocation. I get the basic idea of how to set it up but am not entirely sure how the check-in alert and geofence tie together. Here is my code:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate{
var manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Core Location
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
var latitude: CLLocationDegrees = 43.039278
var longitude: CLLocationDegrees = -87.932479
var center: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var radius: CLLocationDistance = CLLocationDistance(10.0)
var identifier: String = "storeID"
var geoRegion: CLCircularRegion = CLCircularRegion(center: center, radius: radius, identifier: identifier)
}
func showSimpleAlertWithTitle(title: String!, message: String!, viewController: UIViewController) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let action = UIAlertAction(title: "Check-In", style: .Cancel , handler: nil)
alert.addAction(action)
viewController.presentViewController(alert, animated: true, completion: nil)
}
}
Set notifyOnEntry = true on the CLCircularRegion to be notified when entering or exiting the region.
Implement locationManager:didEnterRegion: delegate method to handle the event.
Example:
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
var latitude: CLLocationDegrees = 43.039278
var longitude: CLLocationDegrees = -87.932479
var center: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var radius: CLLocationDistance = CLLocationDistance(10.0)
var identifier: String = "storeID"
var geoRegion: CLCircularRegion = CLCircularRegion(center: center, radius: radius, identifier: identifier)
geoRegion.notifyOnEntry = true
manager.startMonitoringForRegion(geoRegion)
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
showSimpleAlertWithTitle("Entered region \(region.identifier)", message: nil)
}
func showSimpleAlertWithTitle(title: String!, message: String!) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let action = UIAlertAction(title: "Check-In", style: .Cancel , handler: nil)
alert.addAction(action)
presentViewController(alert, animated: true, completion: nil)
}
See: CLRegion.notifyOnEntry

Repeating pin annotation on map

I have just started learning Swift.
Question:
When I touch on map to place the pin annotation and drag my finger it creates repeating line of annotation.
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
var manager:CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
//Manager for current location
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
//Getting touch Gesture to add bookmark
let uilpgr = UILongPressGestureRecognizer(target: self, action: "action:")
uilpgr.minimumPressDuration = 1
uilpgr.numberOfTouchesRequired = 1
map.addGestureRecognizer(uilpgr)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0]
let latitude:CLLocationDegrees = userLocation.coordinate.latitude
let longitude:CLLocationDegrees = userLocation.coordinate.longitude
let latDelta:CLLocationDegrees = 0.002
let lonDelta:CLLocationDegrees = 0.002
let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
map.setRegion(region, animated: true)
}
func action(gestureRecognizer: UIGestureRecognizer) {
let touchPoint = gestureRecognizer.locationInView(self.map)
let newCoordinate: CLLocationCoordinate2D = map.convertPoint(touchPoint, toCoordinateFromView: self.map)
print(newCoordinate)
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinate
annotation.title = "New Place"
annotation.subtitle = "One day I'll go here..."
map.addAnnotation(annotation)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Xcode 8.2 • Swift 3.0.2
You just need to check the gesture recognizer state and make sure if not .Began return. Just add this if condition at the top of your action method:
func action(_ gestureRecognizer: UIGestureRecognizer) {
if gestureRecognizer.state != UIGestureRecognizerState.began {
return
}
// your code
If you would like to allow the user to move the pin while touching you will need to switch the gesture recognizer state and update the annotation coordinate if gestureRecognizer.state changes:
func action(_ gestureRecognizer: UIGestureRecognizer) {
switch gestureRecognizer.state {
case .began:
let annotation = MKPointAnnotation()
annotation.coordinate = mapView.convert(gestureRecognizer.location(in: mapView), toCoordinateFrom: mapView)
annotation.title = "Untitled"
mapView.addAnnotation(annotation)
case .changed:
if let annotation = (mapView.annotations.filter{$0.title! == "Untitled" }).first as? MKPointAnnotation {
annotation.coordinate = mapView.convert(gestureRecognizer.location(in: mapView), toCoordinateFrom: mapView)
}
case .cancelled:
if let annotation = (mapView.annotations.filter{$0.title! == "Untitled" }).first as? MKPointAnnotation {
mapView.removeAnnotation(annotation)
}
// you can also prompt the user here for the annotation title
case .ended:
if let annotation = (mapView.annotations.filter{$0.title! == "Untitled" }).first as? MKPointAnnotation {
let alert = UIAlertController(title: "New Annotation", message: "", preferredStyle: .alert)
var inputTextField: UITextField?
alert.addAction(UIAlertAction(title: "Add", style: .default) { _ in
if let annotationTitle = inputTextField?.text {
annotation.title = annotationTitle
annotation.subtitle = "Lat:\(String(format: "%.06f", annotation.coordinate.latitude)) Lon:\(String(format: "%.06f", annotation.coordinate.longitude))"
}
})
alert.addTextField(configurationHandler: { textField in
textField.placeholder = "Place Description"
inputTextField = textField
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel){ _ in
self.mapView.removeAnnotation(annotation)
})
present(alert, animated: true, completion: nil)
}
default:
print("default")
}
}

Resources