Hello!
From time to time, in non-standard locales (DE-de and EN-it)
the map scale starts showing the value 0 mm instead of the classical 0

Mapbox SDK versions: 5.1.0
iOS/macOS versions: iOS 12
Thanks for this report @racer1988. mm seems clearly incorrect, and to clarify, you're also saying it's best to show 0 instead of 0 m correct?
Also: @Chaoba would you mind commenting on what the behavior is on Android?
cc @mapbox/maps-android
normal behaviour is showing 0 only and I personally think it aligns better with the bar.
@chloekraw On Android, we show 0.
This is definitely a bug - it should show “0” only.
There’s also another bug visible on the screenshot in https://github.com/mapbox/mapbox-gl-native/issues/15197#issue-471776875
The bars on the scalebar should be distributed evenly, but the left bar takes up 60% of the available space.
I haven't had luck repro'ing the initial issue of seeing 0mm or 0ft.
It looks like the issue in https://github.com/mapbox/mapbox-gl-native/issues/15197#issuecomment-514533957 occurs when the scale bar goes from having three distance bars to two.
@racer1988 Have you found a way to repro the initial issue consistently with v5.2.0? Are you seeing it on any specifics devices, or on all devices?
@frederoni opened https://github.com/mapbox/mapbox-gl-native/issues/15356 to track the issue you pointed out. 🙇♀
@jmkiley I think I found a way to reproduce it constantly!
I can reproduce clearly on my iPhone X device with 5.2.0.
You will need a bit of my code and the following steps:
ViewDidAppear of the viewController holding the map0mm from 0I think what makes the bug happening is the following code we use in the viewDidAppear and didDisappear
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
handleZoomOnScale()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
hideScale(animated: false)
}
private func handleZoomOnScale() {
guard configuration.showsScale else {
return
}
mapView.scaleBar.alpha = 1.0
mapView.showsScale = true
hideScaleTimer?.invalidate()
hideScaleTimer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false, block: { [weak self] (timer) in
guard timer.isValid else {
return
}
self?.hideScale()
})
}
private func hideScale(animated: Bool = true) {
hideScaleTimer?.invalidate()
hideScaleTimer = nil
guard animated == true else {
mapView.showsScale = false
return
}
UIView.animate(withDuration: 0.3, delay: 0.0, options: .beginFromCurrentState, animations: { [weak self] in
self?.mapView.scaleBar.alpha = 0.0
}) { [weak self] _ in
self?.mapView.showsScale = false
}
}
@jmkiley As the way I handle the scale bar might impact the internals, I also would like to point out that the same code is also triggering another issue: #15045
probably due to the same method;
func mapView(_ mapView: MGLMapView, regionIsChangingWith reason: MGLCameraChangeReason) {
if reason.contains(.gesturePinch) ||
reason.contains(.gestureZoomIn) ||
reason.contains(.gestureZoomOut) {
handleZoomOnScale()
}
}
@racer1988 thanks for the detailed repro steps.
I strongly suspect this is likely due to the NSCache that's used for the label images being cleared, and a new label for 0 being created:
https://github.com/mapbox/mapbox-gl-native/blob/1ffb417bdb86bfa290dd1984140e7d83ea6ce7fd/platform/ios/src/MGLScaleBar.mm#L370
(A default for 0 is only created when the scale bar is created, via addZeroLabel).
@jmkiley we need to do a few things:
NSCache to NSMutableDictionaryNSNumberFormatter used by addZeroLabel is sufficient.
Most helpful comment
@racer1988 thanks for the detailed repro steps.
I strongly suspect this is likely due to the
NSCachethat's used for the label images being cleared, and a new label for0being created:https://github.com/mapbox/mapbox-gl-native/blob/1ffb417bdb86bfa290dd1984140e7d83ea6ce7fd/platform/ios/src/MGLScaleBar.mm#L370
(A default for
0is only created when the scale bar is created, viaaddZeroLabel).@jmkiley we need to do a few things:
NSCachetoNSMutableDictionaryNSNumberFormatterused byaddZeroLabelis sufficient.