我在swift 3中集成了谷歌地图,当地图画面出现时显示的当前位置没有显示,我在.plist文件中添加了两个键,还设置了CLLocationManager委托和requestAlwaysAuthorization
class MapViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate {
@IBOutlet var mapView: GMSMapView!
var marker: GMSMarker?
override func viewDidLoad() {
super.viewDidLoad()
self.title = "MapVC"
self.doSetupUI()
self.searchLocation()
}
override func viewWillAppear(_ animated: Bool) {
let locationManager : CLLocationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
}
func doGoogleMapSetup(lat : Double , lng : Double) {
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude:lng, zoom:16)
let mapView = GMSMapView.map(withFrame: .zero, camera:camera)
mapView.isMyLocationEnabled = true
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lng)
marker.snippet = ""
marker.appearAnimation = kGMSMarkerAnimationPop
marker.map = mapView
let arrPoints : NSMutableArray = NSMutableArray()
arrPoints.add(UserDefaults.standard.object(forKey: "addressPoints"))
for i in 0..<arrPoints.count {
let path : String = (arrPoints.object(at: i)as! NSMutableArray).object(at: 0) as! String
let route : GMSPath = GMSPath.init(fromEncodedPath: path)!
let polyLine : GMSPolyline = GMSPolyline.init(path: route)
polyLine.strokeWidth = 2.0
polyLine.strokeColor = UIColor.red
polyLine.map = mapView
}
}
答案 0 :(得分:21)
为了显示当前位置,我们在GoogleMaps
的情况下不需要任何位置管理器。我们只需要在 .plist 中添加其中一个键或两者。所以确保钥匙在那里。我使用了NSLocationWhenInUseUsageDescription
密钥。
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow location</string>
另外,请确保您调用了GMSServices
provideAPIKey
方法,并替换为您在google开发者控制台中生成的 API_KEY 。此外,还应启用根据要求的所有相关Google API。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
GMSServices.provideAPIKey("YOUR_API_KEY")
return true
}
所以,我假设您已经在Google开发者控制台中完成了所有设置和操作。
只需在控制器中写下以下行,GoogleMap
就可以显示位置允许/禁止提示并获得用户的许可。
mapView.isMyLocationEnabled = true
但是,这不会将地图设置为当前位置的动画。但您可以手动拖动地图以检查当前位置,您将在当前位置看到一个蓝点。
但是现在我们还想在加载ViewController
时动画到当前位置。现在需要CLLocationManager
到来。因此,在其didUpdateLocation
委托中,我们可以获取当前位置,并且只需将图表设置为当前位置的动画。
所以这是我完整的控制器。
import UIKit
import GoogleMaps
class ViewController: UIViewController,GMSMapViewDelegate,CLLocationManagerDelegate {
@IBOutlet weak var mapView: GMSMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.isMyLocationEnabled = true
mapView.delegate = self
//Location Manager code to fetch current location
self.locationManager.delegate = self
self.locationManager.startUpdatingLocation()
}
//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:14)
mapView.animate(to: camera)
//Finally stop updating location otherwise it will come again and again in this delegate
self.locationManager.stopUpdatingLocation()
}
}
另一种做法是不使用didUpdateLocation
而不使用位置管理器只是使用GMSMapViewDelegate
委托方法mapViewDidFinishTileRendering
func mapViewDidFinishTileRendering(_ mapView: GMSMapView) {
let location = mapView.myLocation
let camera = GMSCameraPosition.camera(withLatitude: (location?.coordinate.latitude)!, longitude:(location?.coordinate.longitude)!, zoom:14)
mapView.animate(to: camera)
}
每次完成地图渲染时都会调用它
但是这有一个限制,每当您使用地图播放时,每当您拖动/捏合/缩放地图时,它总会将您带到当前位置。所以,你可以在这里实现某种bool
变量逻辑。
您可以使用
获取您的位置信息let yourCurrentLocation = mapView.myLocation
确保在设备而不是模拟器上执行此操作。如果您使用的是模拟器,则必须选择一些自定义位置,然后才能看到蓝点。
我已经给出了这种答案。检查此Link。但那是在Swift 2.x中。我在这个答案中发布的那个是在Swift 3.x
中答案 1 :(得分:0)
这有点详细,所以我想留下完整的答案。这是我几年前在零位置遇到的最常见的原因,因为找出了基础知识。因此,您在viewDidLoad中调用CLLocationManager.startLocating()。然后调用设置地图的方法。有时这是有效的,有时它不起作用,因为一方面由CLLocationManager设置权限所花费的时间量导致竞争条件,并且在代码的另一部分中访问用户的位置。让我们看一下事件的顺序,它不起作用:
1)你调用requestAlwaysAuthroization和startLocating 2)在一个线程上触发用户权限设置 3)在ViewController中,您可以请求用户的位置来设置地图 4)它回来没有 5)现在,第2步完成,应用程序可以访问用户的位置,但为时已晚
核心问题是,以请求权限和位置开始的过程需要花费几毫秒的时间。如果您的视图已经设置,则需要几毫秒才能完成viewDidLoad中的方法。当您拥有所需的位置时,您已经请求了它。在我的基于位置的应用中,这导致了太多崩溃。
我的解决方法是,在该视图中制作单个CLLocationManager,使我的起始视图成为委托,以及requestAlwaysAuthorization和startLocating。这样,当我到达需要该位置的视图时,应用程序已经开始定位,并且locationManager.location不是nil。
这种方法显然不适用于每个应用。如果您需要澄清,请告诉我,如果您还需要代码。我有一些公开的iO git repos,我遇到过的项目并解决了这个问题。