Swift 3.0从不同的视图控制器获取用户位置坐标

我有两个视图控制器 – 一个是能够通过locationManager获得用户位置协调的mapView,另一个是我希望能够拉动这些用户坐标的VC。

首先VC:MapView

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { var coordinatesOfUser = locations.last?.coordinate print("The value of usercoordinates are \(coordinatesOfUser)") // here I want to be able to pull this variable, coordinatesOfUser if let location = locations.last { let span = MKCoordinateSpanMake(0.00775, 0.00775) let myLocation = CLLocationCoordinate2DMake(location.coordinate.latitude,location.coordinate.longitude) let region = MKCoordinateRegionMake(myLocation, span) map.setRegion(region, animated: true) } self.map.showsUserLocation = true locationManager.stopUpdatingLocation() } 

第二个VC:

我正在考虑在VC中调用locationManager函数。 这是把坐标拖到这个VC最有效的方法吗? 如果是这样,我该怎么去做呢?

这里有几个选项来解决这个问题:

委托 :你的第二个VC可以有一个委托,允许第一个视图控制器从它获得坐标。 这里的好处是你可以收到更新作为进来。

 protocol MyLocationDelegate: class { func newLocationArrived(location: CLLocation) } class FirstVC: UIViewController, MyLocationDelegate { override func viewDidLoad() { super.viewDidLoad() } func newLocationArrived(location: CLLocation) { print(location) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let dest = segue.destination as? SecondVC { dest.delegate = self } } } class SecondVC: UIViewController, CLLocationManagerDelegate { /// ... ... weak var delegate: MyLocationDelegate? func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { /// do something with the location /// provide the data via delegation delegate?.newLocationArrived(location: CLLocation()) } } 

通知 :通过NSNotificationCenter发布通知。 也可以收到更新,只需通过通知中心,而不是通过代表发送。

postNotificationName:对象:USERINFO:

子视图控制器 :根据第二个视图控制器及其视图是否是第一个视图控制器的子视图,这可以允许直接访问。 并不总是一个选项。

Singleton(CLLocationManager) :如果你打算在整个应用程序的其他地方使用位置服务,你可以使用Singleton将CLLocationManager移动到它自己的类中。 其他视图控制器可以根据其特定需求引用该类。 这在使用后台或重要更改位置时也很有用,因为他们可能需要使用LaunchOptions键来重新启动位置pipe理器。

 class MyLocationManager: CLLocationManager, CLLocationManagerDelegate { static let shared = MyLocationManager() var locations = [CLLocation]() func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { for location in locations { self.locations.append(location) } } } 

我有同样的问题,我最终修正了一个通知,正如kuhncj所说。

这就是代码在最后的样子:

  //Get user location func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { if status == .authorizedWhenInUse { locationManager.startUpdatingLocation() mapView.isMyLocationEnabled = true mapView.settings.myLocationButton = true } else { initialLocation() } } 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() let userInfo: NSDictionary = ["location": location] //Post notification NotificationCenter.default.post(name: NSNotification.Name("UserLocationNotification"), object: self, userInfo: userInfo as [NSObject : AnyObject]) } } 

然后在另一个视图控制器中:

  var userLocation: String? override func viewDidLoad() { super.viewDidLoad() //Observer that receives the notification NotificationCenter.default.addObserver(self, selector: #selector(locationUpdateNotification), name: Notification.Name("UserLocationNotification"), object: nil) } func locationUpdateNotification(notification: NSNotification) { if let userInfo = notification.userInfo?["location"] as? CLLocation { //Store user location self.userLocation = "\(userInfo.coordinate.latitude), \(userInfo.coordinate.longitude)" } } 

然后,我能够使用存储的userLocation另一种方法。