I was watching a course on how to edit maps in Swift and add annotations, but unfortunately the instructor did not talk about how to edit the title and the subtitle of an annotation after adding one on the map, so I wanted to go a little bit further and edit them with my very simple knowledge in Swift.
Here's the code:
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
//add
#IBOutlet weak var titleText: UITextField!
#IBOutlet weak var subtitleText: UITextField!
#IBOutlet weak var buttonAdd: UIButton!
//add
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//add
subtitleText.alpha = 0
titleText.alpha = 0
buttonAdd.hidden = true
//add
// 51.498340, -0.153257
var latitude:CLLocationDegrees = 51.498340
var longitude:CLLocationDegrees = -0.153257
var latDelta:CLLocationDegrees = 0.02
var lonDelta:CLLocationDegrees = 0.02
var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: true)
var annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = "Belgravia"
annotation.subtitle = "I love you!"
mapView.addAnnotation(annotation)
var uilpgr = UILongPressGestureRecognizer(target: self, action: "action:")
uilpgr.minimumPressDuration = 2.0
mapView.addGestureRecognizer(uilpgr)
}
let newAnnotation = MKPointAnnotation()
func action(gestureRecognizer:UIGestureRecognizer) {
var touchPoint = gestureRecognizer.locationInView(self.mapView)
var newCoordinate:CLLocationCoordinate2D = mapView.convertPoint(touchPoint, toCoordinateFromView: self.mapView)
newAnnotation.coordinate = newCoordinate
titleText.alpha = 1
subtitleText.alpha = 1
buttonAdd.hidden = false
mapView.addAnnotation(newAnnotation)
var uilpgr = UILongPressGestureRecognizer(target: self, action: "action:")
uilpgr.minimumPressDuration = 2.0
}
func addPoint(sender: AnyObject) {
newAnnotation.title = titleText.text
newAnnotation.subtitle = subtitleText.text
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Every time I try to write text inside these two and then press the addPoint button in the iOS simulator it'll crash unexpectedly
[Maps.ViewController button:]: unrecognized selector sent to instance...
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 have a UIViewController, inside of this one in my storyboard I have a UITableViewController and a GMSMapView.
Well, I have a service to populate my UITableViewController, with some information and georeferences. The UITableViewController behavior is working perfectly, but when I try to access to my UIViewController the markers aren't added.
class RequestViewController: UIViewController {
#IBOutlet weak var mapView: GMSMapView!
var solicitudes = [SolicitudesModel]()
override func viewDidLoad() {
super.viewDidLoad()
let camera = GMSCameraPosition.camera(withLatitude: 83.4824182, longitude: -88.1776567, zoom: 15)
self.mapView.camera = camera
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(13.4824182, -88.1776567)
marker.title = "My location"
marker.map = self.mapView
}
}
The marker as this point was added.
class RequestTableViewController: UITableViewController {
var reqs = [RequestModel]()
#IBOutlet var RequestTable: UITableView!
override func viewDidLoad() {
var requestVC = RequestViewController()
Alamofire.request(UrlGlobals.retriveInformation()).responseJSON { response in
let json = JSON(response.result.value)
var i: Int = 0
self.reqs.removeAll()
for _ in json.array ?? [] {
//Some code to populate the table
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(CLLocationDegrees(json["lat"].float!), CLLocationDegrees(json["lng"].float!))
marker.title = "Some title"
marker.map = requestVC.mapView
}
self.RequestTable.reloadData()
}
}
}
The json retrieves all the information correctly. How I can access to my primary ViewController and add those google markers?
Right now your RequestViewController is an instance that exists only in viewDidLoad. Make it a class property and you will be able to access it anywhere.
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
I am currently not able to clear the overlay.I would like to clear my overlay that was traveled and then start again. I have looked at a ton of different lines of code and can't seem to figure it out. Could you please help me out on this? I am new to Swift so please play nice :)
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var theMap: MKMapView!
#IBOutlet weak var theLabel: UILabel!
#IBOutlet weak var startTracking: UIButton!
#IBOutlet weak var stopTracking: UIButton!
#IBOutlet weak var clearTrack: UIButton!
var polyline:MKPolyline = MKPolyline()
var manager:CLLocationManager!
var myLocations: [CLLocation] = []
func clearTrack(sender: UIButton){
//label.text = String(myLocations.count)
//stopTracking()
theMap.removeOverlay (polyline)
}
func stopTracking(sender: UIButton) {
manager.stopUpdatingLocation()
myLocations = []
println("Stop making a line")
}
func startTracking(sender: UIButton) {
manager.startUpdatingLocation()
myLocations = []
println("Making a line")
}
override func viewDidLoad() {
super.viewDidLoad()
//Setup our Location Manager
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
//Setup our Map View
theMap.delegate = self
theMap.mapType = MKMapType.Hybrid
theMap.showsUserLocation = true
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
theLabel.text = "\(locations[0])"
myLocations.append(locations[0] as CLLocation)
let spanX = 0.002
let spanY = 0.002
var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
theMap.setRegion(newRegion, animated: true)
if (myLocations.count > 1){
var sourceIndex = myLocations.count - 1
var destinationIndex = myLocations.count - 2
let c1 = myLocations[sourceIndex].coordinate
let c2 = myLocations[destinationIndex].coordinate
var a = [c1, c2]
var polyline = MKPolyline(coordinates: &a, count: a.count)
theMap.addOverlay(polyline)
}
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.yellowColor()
polylineRenderer.lineWidth = 3
return polylineRenderer
}
return nil
}
}
Have you tried using:
func clearTrack(sender: UIButton){
theMap.removeOverlays(theMap.overlays)
}
I am writing an app that has the ability to track a user's location and trace it on a map. There are three buttons, one that starts tracing the path that the user lays down, one is to stop tracing the path the user lays down, and the last is to clear the map of the traced line. I am having trouble setting up the clear button. Can someone please help me set up the #IBAction for the clear path button.
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var theMap: MKMapView!
#IBOutlet weak var startStopTracking: UISegmentedControl!
#IBOutlet weak var clearPath: UIButton!
#IBOutlet weak var label: UILabel!
var manager:CLLocationManager!
var myLocations: [CLLocation] = []
override func viewDidLoad() {
super.viewDidLoad()
//Setup our Location Manager
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
//manager.startUpdatingLocation()
//Setup our Map View
theMap.delegate = self
theMap.mapType = MKMapType.Hybrid
theMap.showsUserLocation = true
//Setup startStopTracking button?
startStopTracking.selectedSegmentIndex = -1
}
#IBAction func indexChanged(sender: UISegmentedControl) {
switch startStopTracking.selectedSegmentIndex
{
case 0:
manager.startUpdatingLocation()
case 1:
manager.stopUpdatingLocation()
default:
break;
}
}
#IBAction func clearPath(sender: UIButton) {
//label.text = String(myLocations.count)
//stopTracking()
//theMap.removeOverlay(overlay: MKOverlay) -> Void
}
func stopTracking() {
manager.stopUpdatingLocation()
myLocations = []
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
//theLabel.text = "\(locations[0])"
myLocations.append(locations[0] as CLLocation)
let spanX = 0.007
let spanY = 0.007
var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
theMap.setRegion(newRegion, animated: true)
if (myLocations.count > 1){
var sourceIndex = myLocations.count - 1
var destinationIndex = myLocations.count - 2
let c1 = myLocations[sourceIndex].coordinate
let c2 = myLocations[destinationIndex].coordinate
var a = [c1, c2]
var polyline = MKPolyline(coordinates: &a, count: a.count)
theMap.addOverlay(polyline)
}
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blueColor()
polylineRenderer.lineWidth = 6
return polylineRenderer
}
return nil
}
}
try this : removes all
for poll in mapkit.overlays {
mapkit.removeOverlay(poll)
}
You have to make your polyline a class property so you have access to it in your clearPath method:
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
...
var polyline: MKPolyline = MKPolyline()
#IBAction func clearPath(sender: UIButton) {
//label.text = String(myLocations.count)
//stopTracking()
theMap.removeOverlay(polyline)
}
}