Xcode Swift Remove MKPolyline - ios

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)
}
}

Related

Swift 3 - MapKit Annotation Touch Listener

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

Defining the title and the subtitle text of an annotation in Swift

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...

Displaying CLLocation in label Xcode 7 Swift 2

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

this class is not key value coding-compliant for the key EventCreate

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!

MapKit Overlay Swift Issue

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)
}

Resources