Im trying to code the CLLocationCoordinate2DMake to change by an array so the lat and long will change depending on the indxPath ...
like i tried here:
var Longitude = ["32.101145","32.074961","",""]
var Latitude = ["34.775163","34.781679","","",""]
//What i tried :
let LightHouseLocation = CLLocationCoordinate2DMake(Longitude[indexPath.row],Latitude[indexPath.row])
// Drop a pin
but of course its throwing errors on me . i will be grateful if anyone could help me, Thank you .
This is how I would do it.
class ViewController: UIViewController {
#IBOutlet weak var map: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var coordinates = Array<CLLocationCoordinate2D>()
coordinates.append(CLLocationCoordinate2DMake(32.101145, 32.074961))
coordinates.append(CLLocationCoordinate2DMake(34.775163, 34.781679))
let pins = coordinates.map { (coordinate) -> MKPointAnnotation in
let pin = MKPointAnnotation()
pin.coordinate = coordinate
return pin
}
self.map.addAnnotations(pins)
}
}
Related
I am using MapKit on Xcode to create a "nearby" hospital/mental health center/call center location app. I want the user to be able to filter the map's results. For instance, if I am looking for hospitals, I only want to see hospital locations appear on the map. So far, to do this, I created a sliding hamburger menu with checkbox-like buttons to use as filters. So for example, you tap the hamburger menu button and you check the box with hospitals so that you only get hospital results on the map. However, I must have messed it up somehow because when I get to the MapViewController, only a black screen appears. Please advise how I can fix this or maybe use a different method entirely to achieve the same goal.
import UIKit
import MapKit
class MapViewController: NSObject, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var trailingMap: NSLayoutConstraint!
#IBOutlet weak var leadingMap: NSLayoutConstraint!
func viewDidLoad() {
mapView.delegate = self as? MKMapViewDelegate
let locationManager = CLLocationManager()
let regionRadius:CLLocationDistance = 1000
locationManager.requestWhenInUseAuthorization()
mapView.showsUserLocation = true
locationManager.startUpdatingLocation()
}
var hamburgerMenuIsVisible = false
#IBAction func hamburgerMenu(_ sender: Any) {
if hamburgerMenuIsVisible {
leadingMap.constant = 150
trailingMap.constant = -150
hamburgerMenuIsVisible = true
} else {
leadingMap.constant = 0
trailingMap.constant = 0
hamburgerMenuIsVisible = false
}
}
var mapItems: [MKMapItem] = []
var place = MKLocalSearch.Request() //user's facility search options
var naturalLanguageQuery: String? {
place.naturalLanguageQuery = "hospital"
let place2 = MKLocalSearch.Request()
place2.naturalLanguageQuery = "Mental Health Facility"
let place3 = MKLocalSearch.Request()
place3.naturalLanguageQuery = "Women's Center"
let place4 = MKLocalSearch.Request()
place4.naturalLanguageQuery = "Call Center"
place.region = self.mapView.region
place2.region = self.mapView.region
place3.region = self.mapView.region
place4.region = self.mapView.region
return place.naturalLanguageQuery
}
#IBAction func hospitalButton(_ sender: Any) {
print(mapItems)
}
#IBAction func callCenterButton(_ sender: Any) {
print(mapItems)
}
}
Your ViewController is subclass of UIViewController, so you have to use inheritance from UIViewController instead of NSObject
So, replace this
class MapViewController: NSObject, CLLocationManagerDelegate {
with this
class MapViewController: UIViewController, CLLocationManagerDelegate {
also fix your viewDidLoad method by adding override keyword before func keyword of your viewDidLoad function. That's because you override function from UIViewController. You will have to call super.viewDidLoad() at the begining of this function. So viewDidLoad should look like this
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self as? MKMapViewDelegate
let locationManager = CLLocationManager()
let regionRadius:CLLocationDistance = 1000
locationManager.requestWhenInUseAuthorization()
mapView.showsUserLocation = true
locationManager.startUpdatingLocation()
}
Total noob here to Swift 3. All I need to do is pass a double value from one ViewController to another via the 2 user input text fields. I've tried numerous solutions and have read everything I can find on passing data between ViewControllers. I get a 'fatal error: unexpectedly found nil while unwrapping an Optional value'. I have a real hard time understand the wrapping and unwrapping of the variables and I'm sure it's something simple.
Here is my first ViewController:
import UIKit
var longitude: Double?
var latitude: Double?
class ViewController: UIViewController {
#IBOutlet var getLongitude: UITextField!
#IBOutlet var getLatitude: UITextField!
#IBOutlet var mapbutton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func MapBtn(_ sender: Any) {
performSegue(withIdentifier: "segue", sender: self)
longitude = Double(getLongitude.text!)!
latitude = Double(getLatitude.text!)!
}
}
And this is the SecondViewController:
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let camera = GMSCameraPosition.camera(withLatitude: latitude!, longitude: longitude!, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
view = mapView
// Creates a marker in the center of the map.
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: latitude!, longitude: longitude!)
marker.map = mapView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Avoid global mutable state. Send data from one scene to another.
Try this:
class ViewController: UIViewController {
#IBOutlet weak var longitudeTextField: UITextField!
#IBOutlet weak var latitudeTextField: UITextField!
#IBOutlet weak var mapButton: UIButton!
#IBAction func didTapToMapButton(_ sender: UIButton) {
// I assume your storyboard' name is Main. If not, change it below accordingly
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
// I assume your destination view controller' identifier and type is SecondViewController. If not, change it below accordingly.
if let secondViewController = mainStoryboard.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController {
if let longitude = Double(longitudeTextField.text),
let latitude = Double(latitudeTextField.text) {
secondViewController.latitude = latitude
secondViewController.longitude = longitude
}
present(secondViewController, animated: true, completion: nil)
}
}
}
class SecondViewController: UIViewController {
var latitude: Double?
var longitude: Double?
override func viewDidLoad() {
super.viewDidLoad()
if let latitude = latitude,
let longitude = longitude {
let camera = GMSCameraPosition.camera(withLatitude: latitude, longitude: longitude, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
view = mapView
// Creates a marker in the center of the map.
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
marker.map = mapView
}
}
}
1st, Unwrapping. when you try to unwrap the variable, rather forcely unwrap it, it's better test if it's nil, or you could use if let to safely unwrap it.
2nd, pass variable from one VC to another. As you know, in iOS, those VCs instances are like any other variable. All you need to do is trying to fetch a reference to that VC, then assign the Double to its accessible variable. Take a look at this link
You could create a segue between the two controllers and pass the variable by overriding prepare for segue.
Pass that variable to the new controller and load that information to its outlet on viewDidAppear or viewWillAppear.
self.prepare(for: "segueName", sender: self)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueName" {
if let vc = segue.destination as? DestinationViewController {
// Pass Data to New View Controller
}
}
}
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.
I have a problem with loading coordinates for a custom UIView that has been linked through IBOutlet and subclassed as GMSMapView. The mapView loads but it always shows the wrong location every time (always London as I presume that is the default). But if I change self.mapView to self.view, the coordinates load correctly within the map. I have no clue why loading coordinates with a custom UIView doesn't work while using the superview works. Thank you in advanced!
#IBOutlet var mapView: GMSMapView!
override func loadView() {
super.loadView()
let kCameraLatitude = 37.314617900000002
let kCameraLongitude = -121.7901318
let camera = GMSCameraPosition.cameraWithLatitude(kCameraLatitude,
longitude: kCameraLongitude, zoom: 1)
let newMapView = GMSMapView.mapWithFrame(self.mapView.frame, camera: camera)
self.mapView = newMapView
}
I had the same problem.
I fixed it by changing the view camera only as such:
#IBOutlet var mapView: GMSMapView!
override func loadView() {
super.loadView()
let kCameraLatitude = 37.314617900000002
let kCameraLongitude = -121.7901318
let camera = GMSCameraPosition.cameraWithLatitude(kCameraLatitude,
longitude: kCameraLongitude, zoom: 1)
self.mapView.camera = camera
}
I am aware that there are many other questions like this however I assure you this is not a duplicate as far as I can tell. As you can see in the code below I have not marked any values as Optional however I keep getting this error. It crashes when I run the snapNext value highlighting the
viewMap.camera = newLocation
Here is the full code below, I have the viewMap linked to just a regular UIView
import UIKit
import MapKit
import GoogleMaps
class ViewController: UIViewController {
var camera = GMSCameraPosition.cameraWithLatitude(33.600727, longitude: -117.900840, zoom: 16.9)
#IBOutlet weak var viewMap: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
viewMap.camera = camera
viewMap = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
viewMap.myLocationEnabled = true
viewMap.settings.myLocationButton = true
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(33.600727, -117.900840)
marker.title = "Newport Beach"
marker.snippet = "California"
marker.map = viewMap
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func snapNext(sender: AnyObject) {
let newLocation = GMSCameraPosition.cameraWithLatitude(33.622578, longitude: -117.911099, zoom: 16.9)
viewMap.camera = newLocation
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Your error is in the line:
viewMap = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
Here you are setting the map to a new anonymous object and because the map property is weak it will be set to nil automatically as soon as the anonymous object goes out of scope (i.e. when viewDidLoad completes).
Either you want to create the object in the storyboard; in which case leave it as a weak outlet, or you just want it as a 'normal' property; in which case remove the weak and IBOutlet.
import UIKit
import MapKit
import GoogleMaps
class ViewController: UIViewControllerGMSMapViewDelegate , CLLocationManagerDelegate {
var camera:GMSCameraPosition!
#IBOutlet weak var viewMap: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
camera = GMSCameraPosition.cameraWithLatitude(33.600727, longitude: -117.900840, zoom: 16.9)
viewMap.camera = camera
viewMap = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
viewMap.myLocationEnabled = true
viewMap.delegate=self
viewMap.settings.myLocationButton = true
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(33.600727, -117.900840)
marker.title = "Newport Beach"
marker.snippet = "California"
marker.map = viewMap
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func snapNext(sender: AnyObject) {
camera = GMSCameraPosition.cameraWithLatitude(33.622578, longitude: -117.911099, zoom: 16.9)
viewMap.camera = camera
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
As you've already pointed out the viewMap is nil. Why it's getting released, I do not know (Need more info to know that). But I know that you can prevent it by removing the weak keyword.
#IBOutlet weak var viewMap: GMSMapView!
However, this might lead to leaks if you have retain cycles between your viewMap and your view controller.