Switching the MKMapView display language

Viewed 4861

Is it possible to switch the underlying language of MKMapView to a different one than the system locale?

For example, if the address displays translated street names (English) but I need to see the native language translations (e.g. in mainland China or Japan).

A alternative to this is to include a local Map Engine (like Baidu) but I wish to see if iOS can do that out of the box.

5 Answers

The Maps application has an option for showing labels in the local language instead of the system language, but this option isn’t available to MapKit.

The Mapbox Maps SDK for iOS does have an option for localizing labels into either the local language in each region or to one of nine languages globally (based on OpenStreetMap and Wikidata).

To change all the labels on the map to the system language, have your MGLMapViewDelegate object implement the -mapView:didFinishLoadingStyle: method, then call the -[MGLStyle localizeLabelsIntoLocale:] method.

In Swift:

func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
    // Into the system language
    style.localizeLabels(into: nil)
    // Into Simplified Chinese
    style.localizeLabels(into: Locale(identifier: "zh-Hans"))
    // Into the local language where a given feature is located
    style.localizeLabels(into: Locale(identifier: "mul"))
}

Or in Objective-C:

- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
    // Into the system language
    [style localizeLabelsIntoLocale:nil];
    // Into Simplified Chinese
    [style localizeLabelsIntoLocale:[NSLocale localeWithLocaleIdentifier:@"zh-Hans"]];
    // Into the local language where a given feature is located
    [style localizeLabelsIntoLocale:[NSLocale localeWithLocaleIdentifier:@"mul"]];
}

There are also options for localizing certain kinds of features, such as only streets or only landmarks. See this document for more details.

By forcing the app default language one can overcome this constraint. Though pricey, it does pay off.

let langCultureCode: String = "en"
let defaults = UserDefaults.standard
defaults.set([langCultureCode], forKey: "AppleLanguages")
defaults.synchronize() 
// UserDefaults.standard.set(["AR"], forKey: "AppleLanguages") // case Arabic

In my application users with Arabic based devices were erroneously searching out of my database with their Arabic country and city names.

regionDidChangeAnimated?

    // الرياض, السعودية
    // دبي ، الإمارات
    // القاهرة، مصر

Forcibly ignoring the device default language does not come freely. Restoring back my Mapview functionality, made my app abandon any localized string. And there were plenty.

enter image description here

regionDidChangeAnimated?

// Riyadh, Saudi Arabia 
// Dubai , United Arab Emirates
// Cairo , Egypt
  • Odd thing the mapView ignores my app default language setup and renders labels with user default language. Which happens to be an accidental advantage

Just do style.localizeLabels(into: Locale.current) in your mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) function.

Make sure that your app has enabled that certain language in the project settings and that MapBox supports that language.

Related