Swift 3.0 从不同的视图控制器获取用户位置坐标
Swift 3.0 Get User Location Coordinates from Different View Controller
我有两个视图控制器 - 一个带有能够通过 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 的最有效方法吗?如果是这样,我该怎么做?
这里有几个选项可以解决这个问题:
Delegation:您的第二个 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())
}
}
Notifications: Post 通过 NSNotificationCenter 的通知。也能够在进来时接收更新,只需通过通知中心而不是通过委托发送。
postNotificationName:object:userInfo:
子视图控制器:根据第二个视图控制器及其视图是否是第一个视图控制器的子视图,这可能允许直接访问。并不总是一个选择。
Singleton (CLLocationManager):如果您打算在整个应用程序的其他地方使用位置服务,您可以将 CLLocationManager 移动到它自己的 class 中,并使用 Singleton .其他视图控制器可以参考 class 以满足他们的特定需求。这在使用背景或重大更改位置时也很有用,因为他们可能需要使用 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)
}
}
}
我遇到了同样的问题,最后我用通知修复了它,正如 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 用于其他方法。
我有两个视图控制器 - 一个带有能够通过 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 的最有效方法吗?如果是这样,我该怎么做?
这里有几个选项可以解决这个问题:
Delegation:您的第二个 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())
}
}
Notifications: Post 通过 NSNotificationCenter 的通知。也能够在进来时接收更新,只需通过通知中心而不是通过委托发送。
postNotificationName:object:userInfo:
子视图控制器:根据第二个视图控制器及其视图是否是第一个视图控制器的子视图,这可能允许直接访问。并不总是一个选择。
Singleton (CLLocationManager):如果您打算在整个应用程序的其他地方使用位置服务,您可以将 CLLocationManager 移动到它自己的 class 中,并使用 Singleton .其他视图控制器可以参考 class 以满足他们的特定需求。这在使用背景或重大更改位置时也很有用,因为他们可能需要使用 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)
}
}
}
我遇到了同样的问题,最后我用通知修复了它,正如 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 用于其他方法。