You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何在一个ViewController保存当前位置坐标并传递至另一个?

Swift页面间位置传递问题解决方案

嘿,我来帮你搞定这个位置传递的问题~ 先给你解答最关心的点:用函数返回值保存坐标其实不太合理,因为定位是异步操作——你调用定位方法后,系统需要一点时间才能拿到位置数据,同步的函数返回值大概率会先返回空或者默认值,等真正拿到位置的时候,返回值早就没用了。

下面给你几种适合异步场景的传值方案,都是Swift开发里常用的:

方案一:闭包回调 + 属性赋值(适合直接跳转的场景)

如果是从VC A跳转到VC B,你可以等定位完成后,再把位置传给VC B的属性。比如:

首先在VC B里定义一个接收位置的属性:

import CoreLocation

class ViewControllerB: UIViewController {
    var userLocation: CLLocationCoordinate2D?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 拿到位置后在这里做展示逻辑
        if let location = userLocation {
            print("展示位置:\(location.latitude), \(location.longitude)")
        }
    }
}

然后在VC A里,等定位回调拿到位置后,再跳转并赋值:

import CoreLocation

class ViewControllerA: UIViewController, CLLocationManagerDelegate {
    let locationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let currentLocation = locations.last?.coordinate else { return }
        locationManager.stopUpdatingLocation() // 拿到位置就停止更新
        
        // 跳转到VC B并传值
        let vcB = storyboard?.instantiateViewController(withIdentifier: "ViewControllerB") as! ViewControllerB
        vcB.userLocation = currentLocation
        navigationController?.pushViewController(vcB, animated: true)
    }
}

方案二:单例类存储(适合多页面共享位置)

如果你的APP不止VC B需要这个位置,可以创建一个全局的单例类来保存位置,VC A更新它,VC B直接读取:

// 全局单例类
import CoreLocation

class LocationStore {
    static let shared = LocationStore()
    private init() {} // 禁止外部实例化
    
    var userCurrentLocation: CLLocationCoordinate2D?
}

VC A里更新位置:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let currentLocation = locations.last?.coordinate else { return }
    locationManager.stopUpdatingLocation()
    LocationStore.shared.userCurrentLocation = currentLocation
}

VC B里读取展示:

override func viewDidLoad() {
    super.viewDidLoad()
    if let location = LocationStore.shared.userCurrentLocation {
        print("展示位置:\(location.latitude), \(location.longitude)")
    }
}

方案三:通知中心(适合位置动态更新的场景)

如果VC B已经在后台,或者需要实时接收位置更新,可以用通知中心:

VC B里注册通知:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(handleLocationUpdate(_:)), name: NSNotification.Name("UserLocationUpdated"), object: nil)
}

@objc func handleLocationUpdate(_ notification: Notification) {
    if let location = notification.userInfo?["location"] as? CLLocationCoordinate2D {
        print("收到更新后的位置:\(location.latitude), \(location.longitude)")
        // 这里做展示逻辑
    }
}

// 记得销毁通知
deinit {
    NotificationCenter.default.removeObserver(self)
}

VC A里发送通知:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let currentLocation = locations.last?.coordinate else { return }
    locationManager.stopUpdatingLocation()
    NotificationCenter.default.post(name: NSNotification.Name("UserLocationUpdated"), object: nil, userInfo: ["location": currentLocation])
}

小提醒

不管用哪种方案,都要注意定位权限的申请,info.plist里记得加NSLocationWhenInUseUsageDescription或者NSLocationAlwaysAndWhenInUseUsageDescription的描述,不然定位会失败。

另外,如果你的跳转逻辑是用户主动触发(比如点击按钮),那最好在按钮点击前就提前启动定位,确保点击时已经拿到位置,或者在按钮点击后等待定位完成再跳转。

内容的提问来源于stack exchange,提问作者Cheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:07:06