2017-07-06 12 views
0

私は2つのView Controllerを持っています.1つはlocationManagerを介してユーザーの位置座標を取得できるmapView、もう1つはこれらのユーザー座標を取得できるVCです。Swift 3.0別のView Controllerからユーザーの位置座標を取得

まず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に座標を引き込む最も効率的な方法ですか?もしそうなら、私はそれをどうやってやりますか?

委任::あなたのsecondVCはそれから座標を取得するための最初のビューコントローラを可能にデリゲートを持つことができます。ここ

+0

MVVMパターンhttp://rasic.info/bindings-generics-swift-and-mvvm/で簡単に実現できます。両方のビューコントローラに1つのビューモデルを使用します。 –

答えて

2

は、これを解決するカップルのオプションがあります。 。ここでの利点が入って来て、あなたが更新を受け取る可能性があることです

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:

子ビューコントローラ:2番目のビューコントローラとそのビューは最初の子であるかどうかに応じて、これは直接アクセスされる可能性があります。必ずしもオプションではありません。

シングルトン(CLLocationManager):アプリを通して他の場所に位置サービスを使用する場合は、シングルトンを持つ独自のクラスにCLLocationManagerを移動することができます。他のView Controllerは、その特定のニーズに合わせてそのクラスを参照できます。これは、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) 
     } 
    } 
} 
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を使用することができました。

関連する問題