Google Maps API IOS cannot load new coordinates with custom UIView - ios

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
}

Related

Change CLLocationCoordinate2DMake With array by indexPath

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

Add markers from UITableViewController to UIViewController

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.

What is the difference between default view and UIView?

I am using Google Map in my app. When I use self.view = map that map in a GMSMapView all is working okay.
But when I create an UIView with IBOutlet (thing with name mapView) and use to show map with markers, all the things i get is just an empty UIView.
So, what's difference is between self.view = map and self.mapView = map? What should I do?
You must use GMSMapViewDelegate and your mapView must be as GMSMapView
import GoogleMaps
class ViewController: UIViewController,GMSMapViewDelegate{
#IBOutlet weak var mapView: GMSMapView!
override func viewDidLoad() {
self.mapView.delegate = self
}
}

Unexpectedly found Nil unwrapping an Optional value

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.

Resetting saved map pins, iOS Swift

I am working on a small map application, so far I have the code to drop map pins and save them so they remain once the app is reopened, this class is for the main view controller:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate {
var location: CLLocation!
let locationManager = CLLocationManager()
#IBOutlet weak var placesMap: MKMapView!
#IBOutlet weak var addButton: UIBarButtonItem!
#IBOutlet weak var moreStuff: UIButton!
// Popover button action
#IBAction func moreStuff(sender: AnyObject) {
self.performSegueWithIdentifier("showMoreStuff", sender:self)
moreStuff.adjustsImageWhenHighlighted = false
}
#IBAction func addButton(sender: AnyObject) {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: self.placesMap.userLocation.coordinate.latitude, longitude: self.placesMap.userLocation.coordinate.longitude)
self.placesMap.addAnnotation(annotation)
self.locationManager.startUpdatingLocation()
}
// Location function
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.004, longitudeDelta: 0.004))
self.placesMap?.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
let locationDictionary:[String:Double] = ["latitude":center.latitude,"longitude":center.longitude]
var locationArray = [[String:Double]]()
if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") != nil {
locationArray = NSUserDefaults.standardUserDefaults().objectForKey("locationArray") as! [[String:Double]]
}
locationArray.append(locationDictionary)
NSUserDefaults.standardUserDefaults().setObject(locationArray, forKey: "locationArray")
NSUserDefaults.standardUserDefaults().synchronize()
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.placesMap?.showsUserLocation = true
if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") != nil {
for dictionary in NSUserDefaults.standardUserDefaults().objectForKey("locationArray") as! [[String:Double]]{
let center = CLLocationCoordinate2D(latitude: dictionary["latitude"]!, longitude: dictionary["longitude"]!)
let annotation = MKPointAnnotation()
annotation.coordinate = center
self.placesMap?.addAnnotation(annotation)
}
}
}
I want to add a button which allows all pins (memories) to be reset at once. This button is located on a new scene and class, called "PopoverOptions". I have the following code from the class which should do this, but it does not seem to be functioning as no pins disappear from the map once it is pressed by the user!
#IBOutlet weak var resetMemories: UIButton!
#IBAction func resetMemories(sender: AnyObject) {
func removeStoredLocations(){
NSUserDefaults.standardUserDefaults().removeObjectForKey("locationArray")
NSUserDefaults.standardUserDefaults().synchronize()
}
}
Any idea why the pins aren't being removed? I have ensured that the class is linked correctly as well as the buttons outlet / action.
You clear out your user defaults key, but don't change the map view on the view controller that shows those pins. You need to call removeAnnotations to remove the annotations from the map.
You could add a viewWillAppear method that detects that your annotations have been deleted and remove them. Something like this:
func viewWillAppear(_ animated: Bool)
{
if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") == nil
{
if let annotations = self.placesMap.annotations
self.placesMap?.removeAnnotations(annotations)
}
}
The code above is written to only remove the annotations from the map if the entire annotations dictionary was deleted from userDefaults. That way you avoid reloading the annotations every time the view controller regains focus.
BTW, you said your new scene is called "PopoverOptions." If the scene is presented in a popover then the above might not work. (I don't think viewWillAppear gets called on a view controller when a popover is dismissed, but I don't remember for sure.)

Resources