Swift 3 - MapKit Annotation Touch Listener - ios

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

Related

Passing latitude and longitude coordinates into a second view controller

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

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

How to change mapkit map view zoom-level with a slider?

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

Unable to display map on view

I've been learning Xcode (swift 1.2) for the past week, I've just started looking into the Map Kit and I've hit a brick wall.
I'm following this tutorial : MapKit Location
I've added the mapkit to my view, and added the following code into the controller:
#IBOutlet weak var mapView: MKMapView!
let regionRadius: CLLocationDistance = 1000
#IBOutlet var menuButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
centerMapOnLocation(initialLocation)
// Do any additional setup after loading the view.
}
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: false)
}
Yet when I run the app, I see the following image:
Can someone please shed some light into why I'm unable to see the actual map instead of the tiles?
Update
Code below afer feedback from ansers:
#IBOutlet weak var mapView: MKMapView!
#IBOutlet var menuButton: UIBarButtonItem!
var locationManage = CLLocationManager()
var locateCoordinate = CLLocationCoordinate2D()
override func viewDidLoad() {
super.viewDidLoad()
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
centerMapOnLocation(initialLocation)
}
func centerMapOnLocation(location: CLLocation) {
var coordin: CLLocationCoordinate2D = location.coordinate
var viewRegion: MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(coordin, 500, 500)
var adjustedRegion: MKCoordinateRegion = self.mapView.regionThatFits(viewRegion)
self.mapView.setRegion(adjustedRegion, animated: true)
}
Some troubleshooting ideas:
double check that your IBOutlet is connected
check if your simulator has network connection
make the change in viewDidAppear to get visual feedback
try on actual device
try different location, greater radius
double check that you are not changing the coordinates or zoom level again after viewDidLoad
try zooming out and panning on the map to see if the contents changes
Set the delegate and delegate methods, Use this example Code,
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var mapViewOwn: MKMapView!
var locationManage = CLLocationManager()
var locateCoordinate = CLLocationCoordinate2D()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib..
mapViewOwn.delegate = self
locationManage.delegate = self
if CLLocationManager.authorizationStatus() == .NotDetermined {
self.locationManage.requestWhenInUseAuthorization()
}
mapViewOwn.showsUserLocation = true
mapViewOwn.mapType = MKMapType.Standard
mapViewOwn.zoomEnabled = true
mapViewOwn.scrollEnabled = true
locationManage.distanceFilter = kCLDistanceFilterNone
locationManage.desiredAccuracy = kCLLocationAccuracyBest
}
//delegate Methods:
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
}
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
let region : MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 1000, 1000)
mapViewOwn.setRegion(mapViewOwn.regionThatFits(region), animated: true)
}
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
//code here
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
//code here
}

Xcode Swift Remove MKPolyline

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

Resources