Swift Google Maps横屏模式下定位方向显示异常问题求助
横屏模式下Google Maps iOS定位点朝向异常问题解决方案
问题描述
在基于Swift 5.7.2、Xcode 14.2开发的iOS应用中集成Google Map View后,地图显示及相机更新正常,但横屏模式下蓝色定位点的朝向箭头存在90度偏差:竖屏时箭头指向正确(对应手机顶部朝向),切换到横屏后箭头方向与实际朝向偏差90度。
尝试通过GMSMapView.animate(to:)方法设置bearing参数调整,但仅会旋转地图,无法修正定位点本身的朝向。相关代码如下:
// 视图控制器中定义 var navView: GMSMapView! var camera = GMSCameraPosition.camera(withLatitude: latitude, longitude: longitude, zoom: 1) let viewBounds = self.view.bounds navView = GMSMapView.map(withFrame: CGRect(x: 102, y: 0, width: viewBounds.maxX - 205, height: viewBounds.maxY), camera: camera) navView.tag = 10 navView.isMyLocationEnabled = true navView.isTrafficEnabled = true self.view.addSubview(navView) // 位置更新代理方法 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! speed = abs(location.speed) altitude = location.altitude let coordinate = location.coordinate latitude = coordinate.latitude longitude = coordinate.longitude setSpeeds(speed, timeStamp: Int(UInt64(location.timestamp.timeIntervalSince1970))) if let navView = navView { let target = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) navView.animate(to: GMSCameraPosition(target: target, zoom: 15, bearing: location.course, viewingAngle: 0)) } }
解决方案
方案一:修正横屏时的定位点朝向
问题根源在于Google Maps默认使用设备的UI界面方向计算定位点朝向,横屏时设备物理方向与UI方向存在90度偏移,需根据当前界面方向对航向值进行修正:
- 实现获取当前界面朝向的工具方法:
func currentInterfaceOrientation() -> UIInterfaceOrientation { if #available(iOS 13.0, *) { return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .portrait } else { return UIApplication.shared.statusBarOrientation } }
- 在位置更新代理中调整航向值并同步到地图:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! speed = abs(location.speed) altitude = location.altitude let coordinate = location.coordinate latitude = coordinate.latitude longitude = coordinate.longitude setSpeeds(speed, timeStamp: Int(UInt64(location.timestamp.timeIntervalSince1970))) guard let navView = navView else { return } let target = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) var adjustedCourse = location.course // 根据界面方向修正航向 let orientation = currentInterfaceOrientation() switch orientation { case .landscapeLeft: adjustedCourse += 90.0 case .landscapeRight: adjustedCourse -= 90.0 default: break } // 确保角度在0-360范围内 adjustedCourse = fmod(adjustedCourse, 360.0) adjustedCourse = adjustedCourse < 0 ? adjustedCourse + 360.0 : adjustedCourse // 更新相机方位 navView.animate(to: GMSCameraPosition(target: target, zoom: 15, bearing: adjustedCourse, viewingAngle: 0)) // 关键:同步修正后的航向到定位点 navView.myLocationHeading = adjustedCourse }
方案二:禁用朝向箭头,仅显示定位点
若不需要显示朝向,可通过两种方式实现:
方式1:使用自定义Marker替代默认定位点
- 关闭Google Maps自带的定位点:
// 地图初始化时设置 navView.isMyLocationEnabled = false
- 创建自定义蓝色定位Marker,并在位置更新时同步坐标:
// 视图控制器中定义全局Marker var userLocationMarker: GMSMarker? // 地图初始化后创建Marker userLocationMarker = GMSMarker() userLocationMarker?.icon = GMSMarker.markerImage(with: .blue) userLocationMarker?.map = navView // 位置更新时更新Marker位置 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! // ... 原有代码 ... userLocationMarker?.position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) }
方式2:隐藏默认定位点的箭头(谨慎使用)
通过遍历地图子视图隐藏箭头,此方式依赖Google Maps内部视图结构,属于非官方API,可能导致App Store审核不通过:
// 在地图首次加载或位置更新后调用 if let myLocationView = navView.subviews.first(where: { $0.accessibilityIdentifier == "myLocation" }) { for subview in myLocationView.subviews { if subview is UIImageView && subview.frame.width > myLocationView.frame.width / 2 { subview.isHidden = true } } }
内容的提问来源于stack exchange,提问作者jl118
相关产品推荐
相关产品推荐

