我有两个视图控制器 - 一个是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的最有效方法吗?如果是这样,我将如何去做呢?
答案 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用于其他方法。