在我当前的项目中,我希望能够在地图上显示用户的当前位置。
我已经通过Apple提供的requestLocation
方法实现了此功能,但是问题是我的代码继续运行而没有等待requestLocation
函数完成。
流程是这样的:首先,我调用positionController.setPositionViaLocationData()
函数,该函数处理requestLocation
方法的设置和执行。最后,它接收坐标并将其存储在userPosition
的PositionController
成员中。
在下一行代码中,我想通过userPosition
访问PositionController
,但这是我的问题:
线...
var userPosition = positionController.getPosition()
...在
positionController.setPositionViaLocationData()
完成之前执行,因此它采用存储在userPosition
中的默认值。我如何让我的代码在执行之前等待
positionController.setPositionViaLocationData()
var userPosition = positionController.getPosition()
?我已经读过有关Closures和CompletionManagers的资料,但是我没有这些资料对我有用。
这是两个类的代码,首先是调用函数的ViewController:
import UIKit
import GoogleMaps
import CoreLocation
class MapViewController: UIViewController, CLLocationManagerDelegate {
let positionController = PositionController()
override func viewDidLoad() {
super.viewDidLoad()
positionController.setPositionViaLocationData()
var userPosition = positionController.getPosition()
setUserPositionMarkerOnMapAndShowMap(userPositionLatitude: userPosition.userLatitude, userPositionLongitude: userPosition.userLongitude)
}
func setUserPositionMarkerOnMapAndShowMap(userPositionLatitude: Double, userPositionLongitude: Double){
let camera = GMSCameraPosition.camera(withLatitude: userPositionLatitude,
longitude: userPositionLongitude, zoom:3)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera:camera)
let marker = GMSMarker()
self.view = mapView
marker.snippet = "Munich"
marker.appearAnimation = GMSMarkerAnimation.pop
marker.map = mapView
self.view = mapView
}
}
现在我的
PositionController
类:import Foundation
import CoreLocation
class PositionController: CLLocationManager, CLLocationManagerDelegate {
let locationManager: CLLocationManager
var userPosition = Position(longitude: 0,latitude: 0)
override init() {
self.locationManager = CLLocationManager()
print("---------------Init---------------------------")
}
func setPositionViaLocationData(){
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.requestLocation()
}
func setPosition(longitude: Double, latitude: Double){
userPosition.longitude = longitude
userPosition.latitude = latitude
}
func getPosition() -> (userLongitude: Double, userLatitude: Double){
return (userPosition.longitude, userPosition.latitude)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
userPosition.latitude = locValue.latitude
userPosition.longitude = locValue.longitude
}
}
最佳答案
您可以使用委托来通知MapViewController用户位置已更新。
您可以在PositionController类定义上方添加下一个协议
protocol PositionControllerDelegate: class {
func didUpdatePosition(_ newPosition: Position)
}
然后向PositionController添加一个新的可选属性
weak var delegate: PositionControllerDelegate?
然后调用委托方法:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue: CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
userPosition.latitude = locValue.latitude
userPosition.longitude = locValue.longitude
delegate?.didUpdatePosition(userPosition)
}
在MapViewController端,您只需实现协议并将self分配给PositionController的委托。
override func viewDidLoad() {
super.viewDidLoad()
positionController.setPositionViaLocationData()
positionController.delegate = self
var userPosition = positionController.getPosition()
setUserPositionMarkerOnMapAndShowMap(userPositionLatitude: userPosition.userLatitude, userPositionLongitude: userPosition.userLongitude)
}
extension MapViewController: PositionControllerDelegate {
func didUpdatePosition(_ newPosition: Position) {
//Do whatever you want with the position
}
}