Mapbox-gl-native: Scalebar shows 0 mm instead of 0

Created on 23 Jul 2019  ·  10Comments  ·  Source: mapbox/mapbox-gl-native

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

2019071311533698259271

Configuration

Mapbox SDK versions: 5.1.0
iOS/macOS versions: iOS 12

bug iOS

Most helpful comment

@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:

  • [ ] Change NSCache to NSMutableDictionary
  • [ ] Clear/reset this dictionary when the locale changes (ensure we reinstate the 0 label)
  • [ ] Double check that the NSNumberFormatter used by addZeroLabel is sufficient.

All 10 comments

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:

  1. Open a app with the Map.
  2. Zoom back and forth
  3. Swipe up to get to the iPhone home screen
  4. open the app again immediately to trigger a new ViewDidAppear of the viewController holding the map
  5. Start zooming while the scale bar is showing, it jumps to 0mm from 0

I 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:

  • [ ] Change NSCache to NSMutableDictionary
  • [ ] Clear/reset this dictionary when the locale changes (ensure we reinstate the 0 label)
  • [ ] Double check that the NSNumberFormatter used by addZeroLabel is sufficient.
Was this page helpful?
0 / 5 - 0 ratings