mapbox / mapbox/mapbox-navigation-ios
Wrong map view orientation when device is moving in landscape mode
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 918
- Forks
- 326
- Avg merge
- 1h 16m
- Merged PRs (30d)
- 3
Description
I am using custom mapbox turn-by-turn navigation in our bike app. Navigation should work in landscape mode and camera should follow user with heading. Everything works fine when I'm testing the navigation in office by simulating location changes, but the problem occurs when I put the device on bike and start to ride.
After few hundred meters map view changes orientation to portrait and, because device is in landscape/faceUp mode, user heading indicator shows wrong direction. I've tried with few approaches but result was the same. First implementation was with userTrackingMode set to followWithHeading. Second one was with userTrackingMode set to follow and I was changing map view direction to fit current CLLocationManager heading. The last one was with userTrackingMode set to follow and I was changing camera to point current CLLocationManager heading.
The last approach code example
MGLMapView initialization:
mapNavigationView.styleURL = mapStyle.url
mapNavigationView.delegate = self
mapNavigationView.showsUserLocation = true
mapNavigationView.userTrackingMode = .follow
mapNavigationView.compassView.isHidden = true
mapNavigationView.attributionButton.isHidden = true
mapNavigationView.logoView.isHidden = true
mapNavigationView.direction = 0
output
.heading
.asDriverIgnoringErrors()
.drive(onNext: { [unowned self] in
guard self.isUserNavigating else { return }
var heading: CLLocationDirection
switch UIApplication.shared.statusBarOrientation {
case .landscapeLeft:
heading = $0 - 90
case .landscapeRight:
heading = $0 + 90
default:
heading = $0
}
self.zoomToUser(withHeading: heading)
})
.disposed(by: disposeBag)
func zoomToUser(
fromDistance: CLLocationDistance = Constants.Map.distance,
withPitch pitch: CGFloat = Constants.Map.pitch,
withAltitude altitude: CLLocationDistance = Constants.Map.altitude,
withHeading heading: CLLocationDirection = Constants.Map.heading
) {
guard let center = mapNavigationView.userLocation?.coordinate else { return }
let camera = MGLMapCamera(lookingAtCenter: center,
acrossDistance: fromDistance,
pitch: pitch,
heading: heading)
camera.altitude = altitude
mapNavigationView.fly(to: camera, completionHandler: nil)
}
I thought that device orientation changes was the cause of the problem, but it occurs when device is in landscape/faceUp mode all the time too.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the MGLMapView initialization and the heading stream that calls zoomToUser, comparing behavior during simulated movement with physical movement while the device remains landscape/faceUp. Check how userTrackingMode, statusBarOrientation, CLLocationManager heading, and camera direction interact. Done means the map remains correctly oriented in landscape and the user heading indicator points in the direction of travel.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, swift
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100