Swift 3.0从不同的View Controller获取用户位置坐标

时间:2017-07-06 18:26:33

标签: ios swift dictionary mkmapview coordinates

我有两个视图控制器 - 一个是mapView,它能够通过locationManager获得用户位置协调,另一个是我希望能够提取这些用户坐标的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的最有效方法吗?如果是这样,我将如何去做呢?

2 个答案:

答案 0 :(得分:2)

以下是一些解决此问题的方法:

委派:您的secondVC可以有一个委托,允许第一个视图控制器从中获取坐标。这里的优点是你可以收到更新。

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键来重新启动位置管理器。

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

答案 1 :(得分:0)

我有同样的问题,我终于用通知修复了它,正如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用于其他方法。