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

Swift iOS中Google Maps的CLLocationManager didUpdateLocations不更新相机问题

解决Google Map跟随用户位置移动的问题

核心问题分析

  1. GMSMapView为局部变量:你在viewDidLoad中创建的navView是局部变量,后续无法在位置更新方法中引用,导致无法修改地图相机位置。
  2. 位置更新方法签名错误:你写的didUpdateLocations是旧Objective-C兼容语法,Swift 5.7.2下不会被系统触发,必须使用符合Swift规范的签名。

修正步骤及完整代码

1. 将GMSMapView改为类属性

在ViewController类中声明navView属性,确保整个类可访问:

import UIKit
import GoogleMaps
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {
    var manager: CLLocationManager?
    // 声明为类属性,方便后续更新地图
    var navView: GMSMapView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        manager = CLLocationManager()
        manager?.delegate = self
        manager?.desiredAccuracy = kCLLocationAccuracyBest
        // 根据场景选择授权类型,前台定位用WhenInUse更合理
        manager?.requestWhenInUseAuthorization()
        manager?.startUpdatingLocation()
        
        let viewBounds = self.view.bounds
        // 初始用默认坐标,后续由位置更新回调修正
        let defaultCoordinate = CLLocationCoordinate2D(latitude: 51.0447, longitude: -114.0719)
        let camera = GMSCameraPosition.camera(withTarget: defaultCoordinate, zoom: 15.0)
        navView = GMSMapView.map(withFrame: CGRect(x: 130, y: 10, width: viewBounds.maxX - 135 * 2, height: viewBounds.maxY - 20), camera: camera)
        navView.isMyLocationEnabled = true
        // 可选:开启内置的定位按钮,方便用户手动回到当前位置
        navView.settings.myLocationButton = true
        self.view.addSubview(navView)
    }
    
    // 修正后的Swift标准位置更新回调
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // 取数组最后一个元素作为最新位置
        guard let latestLocation = locations.last else { return }
        let latestCoordinate = latestLocation.coordinate
        
        // 平滑移动地图相机到当前位置
        let cameraUpdate = GMSCameraUpdate.setTarget(latestCoordinate, zoom: navView.camera.zoom)
        navView.moveCamera(cameraUpdate)
        
        // 可选:如果需要跟随用户移动方向,替换为下面代码
        // let cameraUpdate = GMSCameraUpdate.setTarget(latestCoordinate, bearing: latestLocation.course, zoom: navView.camera.zoom)
        // navView.animate(with: cameraUpdate)
    }
    
    // 可选:处理定位权限变化,提升用户体验
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .authorizedWhenInUse, .authorizedAlways:
            manager.startUpdatingLocation()
        case .denied, .restricted:
            // 提示用户开启权限
            let alert = UIAlertController(title: "定位权限未开启", message: "请在设置中开启定位权限以使用地图功能", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "确定", style: .default))
            present(alert, animated: true)
        default:
            break
        }
    }
}

2. 关键改动说明

  • 类属性声明:把navView改为类属性,解决后续无法引用的问题。
  • 修正回调签名:使用Swift标准的locationManager(_:didUpdateLocations:)方法,确保系统能正确触发位置更新回调。
  • 平滑相机更新:用GMSCameraUpdate.setTarget创建更新指令,通过moveCamera实现平滑移动,避免地图跳转生硬。
  • 权限处理:添加didChangeAuthorization方法,处理权限拒绝或受限的情况,引导用户开启权限。

额外注意事项

  • Info.plist配置:必须在Info.plist中添加权限描述键,比如NSLocationWhenInUseUsageDescription(前台定位)或NSLocationAlwaysAndWhenInUseUsageDescription(前后台定位),否则授权请求会被系统忽略。
  • 初始位置优化:viewDidLoad中直接获取manager?.location大概率为nil(定位尚未完成),因此用默认坐标初始化,后续靠回调修正。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:55:34