I want to display user's current location immediately after they open the app. I use Mapbox iOS SDK. But it doesn't work at all. I don't know what's wrong. I can only see an irrelevant map after I open it.
import UIKit
import Mapbox
import CoreLocation
class ViewController: UIViewController, MGLMapViewDelegate, CLLocationManagerDelegate
{
#IBOutlet weak var mapView: MGLMapView!
let locationManager = CLLocationManager()
override func viewDidLoad()
{
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: Location Delegate Methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
let mapView = MGLMapView(frame: view.bounds)
mapView.userTrackingMode = .Follow
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
mapView.setCenterCoordinate(center, zoomLevel: 15, animated: true)
view.addSubview(mapView)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print ("Errors:" + error.localizedDescription)
}
}
I think the issue might be the iOS Simulator. When you run an app on the simulator, it doesn't simulate your location until you tell it to.
If you look at your Xcode, you'll see a navigate button at the bottom.
Try changing the location to something, and it should show up :)
Related
I am trying to get and display the user's location, but the simulator will only load the country I am in. I set up the required info.plist sections (privacy - location when in use and always), linked the mapView in Main.storyoard to the delegate (control-dragged to View Controller Icon), attached the IBOutlet (checked it to make sure it is properly connected) and wrote this code in viewController.swift:
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
var locationManager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
mapView.mapType = MKMapType.standard
let location = locations[0]
let myLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: myLocation, span: span)
mapView.setRegion(region, animated: true)
self.mapView.showsUserLocation = true
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I am just getting my feet wet with MapKit and this issue has been keeping me back for quite some time. Would appreciate any help.
Please use iPhone Device to get the current location. In the simulator, you have to set location then get that location. So can do this easily using the device. Your code will work with the real device.
If you want to test it with simulator the follow https://medium.com/#abhimuralidharan/location-simulation-in-xcode-ff7db9042710
I have integrated GoogleMap using pod in my project but map is not loading. When I make my mapViewController as a initial ViewController then its working fine.
But when I push or present MapViewController then its showing me the blank screen.
I am using XCode 9.1, my project deployment Target is 9.0 and Google Maps SDK for iOS version: 2.5.30219.0.
Thanks in Advance.
Here is my MapViewController code:
import UIKit
import GoogleMaps
class MapViewController: UIViewController {
#IBOutlet weak var mapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
let camera = GMSCameraPosition.camera(withTarget: CLLocationCoordinate2DMake(18.486726, 73.798394), zoom: 10)
mapView.camera = camera
}
}
Console Log:
CoreData: annotation: Failed to load optimized model at path
/Users/pritamsing.salunkhe/Library/Developer/CoreSimulator/Devices/6DD7C0EA-320F-4E99-BEC9-672046198800/data/Containers/Bundle/Application/04CC747F-5B2D-4588-883A-E814D4EE0769/HimmatPlus.app/GoogleMaps.bundle/GMSCacheStorage.momd/StorageWithTileVersionID.omo
Don't use IBOutlet for googleMap in Storyboard & also Don't set subclass for GMSMapView.
implement your map by programmatically. Its will boost your Map UI faster
/// Google MapView
var mapView: GMSMapView!
self.mapView = GMSMapView(frame: CGRect(x: 0, y: 64, width: self.currentDeviceSize.width, height: self.bottomBgView.frame.minY - 64))
// self.mapView.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin]
self.mapView.settings.allowScrollGesturesDuringRotateOrZoom = true
// self.mapView.settings.myLocationButton = true //Enable My location button
// self.mapView.isTrafficEnabled = true //Enable traffic
// self.mapView.isBuildingsEnabled = true // Building Enable
// self.mapView.isMyLocationEnabled = true //My location Enabled
// let containerView: GMSMapView = self.mapView
self.view.addSubview(self.mapView)
Try with the proper implementation of Google map.
#IBOutlet weak var mapView: GMSMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
self.configureMap()
}
func configureMap(){
mapView.delegate = self
//Check for Location Services
if (CLLocationManager.locationServicesEnabled()) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestWhenInUseAuthorization()
}
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
}
MapView Delegate method
//MARK:- MapView delegate
extension YourViewControllerName: GMSMapViewDelegate, CLLocationManagerDelegate{
//Location Manager delegates
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude: (location?.coordinate.longitude)!, zoom: 12.0)
self.mapView?.animate(to: camera)
// To stop updating the location again
self.locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("error description:\(error.localizedDescription)")
}
}
Key In plist file.
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your custom message.</string>
I have successfully made an app that shows a blinking blue dot where the user currently is. However as of right now the center of the screen does not follow the blue dot as the user moves, so if the user moves the blue dot just exits the screen and the user would have to scroll to keep up with it. That isnt user friendly! I have the below code:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
var mapp = MKMapView.self
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if (CLLocationManager.locationServicesEnabled())
{
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.map.showsUserLocation = true
}
else
{
print("Location services are not enabled")
}
}
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: 0.002, longitudeDelta: 0.002))
self.map.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
}
My only thoughts are that I could get rid of the "stopUpdatingLocation() section and maybe then it would continuously update the region with the new center for every new location, however I am not sure if not having the stopUpdatingLocation is bad practice? Thanks for all advice!
Use userTrackningMode which causes the map view to center the map on that location and begin tracking the user’s location. If the map is zoomed out, the map view automatically zooms in on the user’s location, effectively changing the current visible region.
To use it
mapView.setUserTrackingMode(.follow, animated:true)
In a custom tableViewCell , I connect a View which is a google map class to the custom class
However it seems that these line of code doesn't run in the custom cell that I created
This cell is part of a tableView, I tried to instantiate this cell for example var gmapsCell = GMapTableViewCell in the viewDidLoad of the TableView but it seems it will always returns nil
So I change my approach to below codes
import UIKit
import GoogleMaps
class GMapTableViewCell: UITableViewCell, GMSMapViewDelegate {
let locationManager = CLLocationManager()
#IBOutlet var mapView: GMSMapView!
override func awakeFromNib() {
super.awakeFromNib()
locationManager.requestAlwaysAuthorization()
// For use in foreground
locationManager.requestWhenInUseAuthorization()
mapView.delegate = self
mapView.settings.myLocationButton = true
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension GMapTableViewCell: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .AuthorizedWhenInUse {
locationManager.startUpdatingLocation()
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
locationManager.stopUpdatingLocation()
}
}
}
The problem right now is that
override func awakeFromNib() {
super.awakeFromNib()
locationManager.requestAlwaysAuthorization()
// For use in foreground
locationManager.requestWhenInUseAuthorization()
mapView.delegate = self
mapView.settings.myLocationButton = true
}
This will never run. My goal is simply to get to the device's current location. Are there any equivalent of viewDidLoad for custom cell?
You need to add "NSLocationWhenInUseUsageDescription" key as a string type in info.plist for the location Manager to start updating locations.
All that code inside awakeNib() should be written in tableView:cellForRowAtIndexPath.
Set all the delegates there.
It will work fine then.
I was trying to add a button on top of Google maps. i tried everything i could but no help can anyone help me.. in Xcode preview it shows on top but after running the app it come below google map.
Picture after running app
How it looks in XCODE
CODE OF MAP
import UIKit
import GoogleMaps
class HomeViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBAction func refreshLocation(sender: AnyObject) {
locationManager.startUpdatingLocation()
}
#IBOutlet weak var gMapView: GMSMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
self.scrollView.contentSize=CGSizeMake(320, 700)
let camera = GMSCameraPosition.cameraWithLatitude(15.4989, longitude: 73.8278, zoom: 17)
gMapView.camera = camera
gMapView.myLocationEnabled = true
self.view.addSubview(gMapView)
let marker = GMSMarker()
marker.map = self.gMapView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
extension HomeViewController {
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.AuthorizedAlways {
locationManager.startUpdatingLocation()
gMapView.myLocationEnabled = true
gMapView.settings.myLocationButton = true
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
gMapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
locationManager.stopUpdatingLocation()
}
}
}
I found the answer
self.view.bringSubviewToFront(self.view_name)
You need to call bringSubviewToFront on the parent view.
Are you using below method? If yes , make sure you are giving frame to mapview so try to give frame as same as you gave in storyboard.
[GMSMapView mapWithFrame:(CGRect) camera:(GMSCameraPosition *)];