diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/darwin/src/MGLClockDirectionFormatter.m | 2 | ||||
-rw-r--r-- | platform/darwin/src/MGLCompassDirectionFormatter.m | 2 | ||||
-rw-r--r-- | platform/darwin/src/MGLCoordinateFormatter.m | 1 | ||||
-rw-r--r-- | platform/darwin/src/NSBundle+MGLAdditions.h | 19 | ||||
-rw-r--r-- | platform/ios/CHANGELOG.md | 1 | ||||
-rw-r--r-- | platform/ios/app/Base.lproj/Localizable.strings | 138 | ||||
-rw-r--r-- | platform/ios/app/Base.lproj/Main.storyboard | 1 | ||||
-rw-r--r-- | platform/ios/app/MBXOfflinePacksTableViewController.m | 28 | ||||
-rw-r--r-- | platform/ios/app/MBXViewController.m | 104 | ||||
-rw-r--r-- | platform/ios/ios.xcodeproj/project.pbxproj | 24 | ||||
-rw-r--r-- | platform/ios/resources/Base.lproj/Localizable.strings | 75 | ||||
-rw-r--r-- | platform/ios/resources/Compass.png | bin | 1061 -> 1139 bytes | |||
-rw-r--r-- | platform/ios/resources/Compass@2x.png | bin | 1300 -> 1892 bytes | |||
-rw-r--r-- | platform/ios/resources/Compass@3x.png | bin | 2514 -> 3398 bytes | |||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 75 | ||||
-rw-r--r-- | platform/ios/src/MGLUserLocation.m | 3 | ||||
-rw-r--r-- | platform/ios/src/MGLUserLocationAnnotationView.m | 3 |
17 files changed, 384 insertions, 92 deletions
diff --git a/platform/darwin/src/MGLClockDirectionFormatter.m b/platform/darwin/src/MGLClockDirectionFormatter.m index 56740e74e3..8047b41b35 100644 --- a/platform/darwin/src/MGLClockDirectionFormatter.m +++ b/platform/darwin/src/MGLClockDirectionFormatter.m @@ -1,5 +1,7 @@ #import "MGLClockDirectionFormatter.h" +#import "NSBundle+MGLAdditions.h" + #define wrap(value, min, max) \ (fmod((fmod((value - min), (max - min)) + (max - min)), (max - min)) + min) diff --git a/platform/darwin/src/MGLCompassDirectionFormatter.m b/platform/darwin/src/MGLCompassDirectionFormatter.m index efda5705a4..f719745ce6 100644 --- a/platform/darwin/src/MGLCompassDirectionFormatter.m +++ b/platform/darwin/src/MGLCompassDirectionFormatter.m @@ -1,5 +1,7 @@ #import "MGLCompassDirectionFormatter.h" +#import "NSBundle+MGLAdditions.h" + #define wrap(value, min, max) \ (fmod((fmod((value - min), (max - min)) + (max - min)), (max - min)) + min) diff --git a/platform/darwin/src/MGLCoordinateFormatter.m b/platform/darwin/src/MGLCoordinateFormatter.m index 259917717f..4ef5409380 100644 --- a/platform/darwin/src/MGLCoordinateFormatter.m +++ b/platform/darwin/src/MGLCoordinateFormatter.m @@ -1,5 +1,6 @@ #import "MGLCoordinateFormatter.h" +#import "NSBundle+MGLAdditions.h" #import "NSValue+MGLAdditions.h" @implementation MGLCoordinateFormatter { diff --git a/platform/darwin/src/NSBundle+MGLAdditions.h b/platform/darwin/src/NSBundle+MGLAdditions.h index 8a3e5c3c2e..bab70f38bc 100644 --- a/platform/darwin/src/NSBundle+MGLAdditions.h +++ b/platform/darwin/src/NSBundle+MGLAdditions.h @@ -4,6 +4,25 @@ NS_ASSUME_NONNULL_BEGIN +// Strings in the SDK targets must be retrieved from the framework bundle rather +// than the main bundle, which is usually the application bundle. Redefining +// these macros ensures that the framework bundle’s string tables are used at +// runtime yet tools like genstrings and Xcode can still find the localizable +// string identifiers. (genstrings has an -s option that would allow us to +// define our own macros, but Xcode’s Export Localization feature lacks support +// for it.) +// +// As a consequence of this approach, this header must be included in all SDK +// files that include localizable strings. + +#undef NSLocalizedString +#define NSLocalizedString(key, comment) \ + [[NSBundle mgl_frameworkBundle] localizedStringForKey:(key) value:@"" table:nil] + +#undef NSLocalizedStringFromTable +#define NSLocalizedStringFromTable(key, tbl, comment) \ + [[NSBundle mgl_frameworkBundle] localizedStringForKey:(key) value:@"" table:(tbl)] + @interface NSBundle (MGLAdditions) /// Returns the bundle containing the SDK’s classes and Info.plist file. diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 842fadd2fc..2377da7cf1 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -9,6 +9,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CON - The user dot now moves smoothly between user location updates while user location tracking is disabled. ([#1582](https://github.com/mapbox/mapbox-gl-native/pull/1582)) - An MGLAnnotation can be relocated by changing its `coordinate` property in a KVO-compliant way. An MGLMultiPoint cannot be relocated. ([#3835](https://github.com/mapbox/mapbox-gl-native/pull/3835)) - Setting the `image` property of an MGLAnnotationImage to `nil` resets it to the default red pin image and reclaims resources that can be used to customize additional annotations. ([#3835](https://github.com/mapbox/mapbox-gl-native/pull/3835)) +- The SDK is now localizable. No localizations are currently provided, other than English, but if you need a particular localization, you can install the SDK manually and drop a .lproj folder into the framework. ([#4783](https://github.com/mapbox/mapbox-gl-native/pull/4783)) - Fixed an issue preventing KVO change notifications from being generated on MGLMapView’s `userTrackingMode` key path when `-setUserTrackingMode:animated:` is called. ([#4724](https://github.com/mapbox/mapbox-gl-native/pull/4724)) - Rendering now occurs on the main thread, fixing a hang when calling `-[MGLMapView styleURL]` before the map view has fully loaded or while the application is in the background. ([#2909](https://github.com/mapbox/mapbox-gl-native/pull/2909)) - Improved responsiveness when zooming in then immediately panning around. ([#4595](https://github.com/mapbox/mapbox-gl-native/pull/4595)) diff --git a/platform/ios/app/Base.lproj/Localizable.strings b/platform/ios/app/Base.lproj/Localizable.strings new file mode 100644 index 0000000000..8eb0a3e120 --- /dev/null +++ b/platform/ios/app/Base.lproj/Localizable.strings @@ -0,0 +1,138 @@ +/* Offline pack status: completed, expected, bytes */ +"%@ of %@ resources (%@)" = "%1$@ of %2$@ resources (%3$@)"; + +/* Offline pack status: completed, bytes */ +"%@ resources (%@)" = "%1$@ resources (%2$@)"; + +/* Title of the access token prompt */ +"Access Token" = "Access Token"; + +/* Action in the settings action sheet */ +"Add 1,000 Points" = "Add 1,000 Points"; + +/* Action in the settings action sheet */ +"Add 10,000 Points" = "Add 10,000 Points"; + +/* Action in the settings action sheet */ +"Add 100 Points" = "Add 100 Points"; + +/* Action in the settings action sheet */ +"Add Custom Callout Point" = "Add Custom Callout Point"; + +/* Title of offline pack name prompt */ +"Add Offline Pack" = "Add Offline Pack"; + +/* Action in the settings action sheet */ +"Add Test Shapes" = "Add Test Shapes"; + +/* Offline pack status: expected resources */ +"at least %@" = "at least %@"; + +/* Offline pack status */ +"Calculating progress…" = "Calculating progress…"; + +/* No comment provided by engineer. */ +"Cancel" = "Cancel"; + +/* Error title */ +"Can’t Add Offline Pack" = "Can’t Add Offline Pack"; + +/* Message of offline pack name prompt */ +"Choose a name for the pack:" = "Choose a name for the pack:"; + +/* User tracking mode */ +"Course" = "Course"; + +/* Title of a custom callout view */ +"Custom Callout" = "Custom Callout"; + +/* Style name */ +"Dark" = "Dark"; + +/* Action in the settings action sheet */ +"Delete Telemetry Logfile" = "Delete Telemetry Logfile"; + +/* Title of the button for downloading offline pack */ +"Download" = "Download"; + +/* Offline pack status: completed, expected, bytes */ +"Downloading %@ of %@ resources (%@ so far)…" = "Downloading %1$@ of %2$@ resources (%3$@ so far)…"; + +/* Title of a dropped pin annotation */ +"Dropped Pin" = "Dropped Pin"; + +/* Style name */ +"Emerald" = "Emerald"; + +/* Message of the access token prompt */ +"Enter your Mapbox access token to load Mapbox-hosted tiles and styles:" = "Enter your Mapbox access token to load Mapbox-hosted tiles and styles:"; + +/* Error title */ +"Error Downloading Offline Pack" = "Error Downloading Offline Pack"; + +/* Action in the settings action sheet */ +"Hide Collision Boxes" = "Hide Collision Boxes"; + +/* Action in the settings action sheet */ +"Hide Custom Style Layer" = "Hide Custom Style Layer"; + +/* Action in the settings action sheet */ +"Hide Tile Boundaries" = "Hide Tile Boundaries"; + +/* Action in the settings action sheet */ +"Hide Tile Info" = "Hide Tile Info"; + +/* Action in the settings action sheet */ +"Hide Tile Timestamps" = "Hide Tile Timestamps"; + +/* Style name */ +"Hybrid" = "Hybrid"; + +/* Style name */ +"Light" = "Light"; + +/* Title of the settings action sheet */ +"Map Settings" = "Map Settings"; + +/* Error message: name, reason */ +"Mapbox GL encountered an error while downloading the offline pack “%@”: %@" = "Mapbox GL encountered an error while downloading the offline pack “%1$@”: %2$@"; + +/* Error message: name */ +"Mapbox GL was unable to add the offline pack “%@”." = "Mapbox GL was unable to add the offline pack “%@”."; + +/* No comment provided by engineer. */ +"OK" = "OK"; + +/* Action in the settings action sheet */ +"Print Telemetry Logfile" = "Print Telemetry Logfile"; + +/* Action in the settings action sheet */ +"Remove Annotations" = "Remove Annotations"; + +/* Action in the settings action sheet */ +"Reset Position" = "Reset Position"; + +/* Style name */ +"Satellite" = "Satellite"; + +/* Action in the settings action sheet */ +"Show Collision Boxes" = "Show Collision Boxes"; + +/* Action in the settings action sheet */ +"Show Custom Style Layer" = "Show Custom Style Layer"; + +/* Action in the settings action sheet */ +"Show Tile Boundaries" = "Show Tile Boundaries"; + +/* Action in the settings action sheet */ +"Show Tile Info" = "Show Tile Info"; + +/* Action in the settings action sheet */ +"Show Tile Timestamps" = "Show Tile Timestamps"; + +/* Action in the settings action sheet */ +"Start World Tour" = "Start World Tour"; + +/* Style name */ +"Streets" = "Streets"; + diff --git a/platform/ios/app/Base.lproj/Main.storyboard b/platform/ios/app/Base.lproj/Main.storyboard index 75b2b68f9a..72f9a02219 100644 --- a/platform/ios/app/Base.lproj/Main.storyboard +++ b/platform/ios/app/Base.lproj/Main.storyboard @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="PSe-Ot-7Ff"> <dependencies> + <deployment identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> <capability name="Navigation items with more than one left or right bar item" minToolsVersion="7.0"/> </dependencies> diff --git a/platform/ios/app/MBXOfflinePacksTableViewController.m b/platform/ios/app/MBXOfflinePacksTableViewController.m index 9b1a12a933..dea443942c 100644 --- a/platform/ios/app/MBXOfflinePacksTableViewController.m +++ b/platform/ios/app/MBXOfflinePacksTableViewController.m @@ -86,13 +86,13 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac } - (IBAction)addCurrentRegion:(id)sender { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Add Offline Pack" message:@"Choose a name for the pack:" preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Add Offline Pack", @"Title of offline pack name prompt") message:NSLocalizedString(@"Choose a name for the pack:", @"Message of offline pack name prompt") preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.placeholder = [NSString stringWithFormat:@"%@", MGLStringFromCoordinateBounds(self.mapView.visibleCoordinateBounds)]; }]; - [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"") style:UIAlertActionStyleCancel handler:nil]]; - UIAlertAction *downloadAction = [UIAlertAction actionWithTitle:@"Download" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + UIAlertAction *downloadAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Download", @"Title of the button for downloading offline pack") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { MGLMapView *mapView = self.mapView; NSAssert(mapView, @"No map view to get the current region from."); @@ -109,9 +109,9 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac [[MGLOfflineStorage sharedOfflineStorage] addPackForRegion:region withContext:context completionHandler:^(MGLOfflinePack *pack, NSError *error) { if (error) { - NSString *message = [NSString stringWithFormat:@"Mapbox GL was unable to add the offline pack “%@”.", name]; - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Can’t Add Offline Pack" message:message preferredStyle:UIAlertControllerStyleAlert]; - [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; + NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Mapbox GL was unable to add the offline pack “%@”.", @"Error message: name"), name]; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Can’t Add Offline Pack", @"Error title") message:message preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"") style:UIAlertActionStyleDefault handler:nil]]; [self presentViewController:alertController animated:YES completion:nil]; } else { [pack resume]; @@ -154,16 +154,16 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac NSString *statusString; switch (pack.state) { case MGLOfflinePackStateUnknown: - statusString = @"Calculating progress…"; + statusString = NSLocalizedString(@"Calculating progress…", @"Offline pack status"); break; case MGLOfflinePackStateInactive: - statusString = [NSString stringWithFormat:@"%@ of %@ resources (%@)", + statusString = [NSString stringWithFormat:NSLocalizedString(@"%@ of %@ resources (%@)", @"Offline pack status: completed, expected, bytes"), completedString, expectedString, byteCountString]; break; case MGLOfflinePackStateComplete: - statusString = [NSString stringWithFormat:@"%@ resources (%@)", + statusString = [NSString stringWithFormat:NSLocalizedString(@"%@ resources (%@)", @"Offline pack status: completed, bytes"), completedString, byteCountString]; break; @@ -173,9 +173,9 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac numberStyle:NSNumberFormatterDecimalStyle]; } if (progress.maximumResourcesExpected > progress.countOfResourcesExpected) { - expectedString = [@"at least " stringByAppendingString:expectedString]; + expectedString = [NSString stringWithFormat:NSLocalizedString(@"at least %@", @"Offline pack status: expected resources"), expectedString]; } - statusString = [NSString stringWithFormat:@"Downloading %@ of %@ resources (%@ so far)…", + statusString = [NSString stringWithFormat:NSLocalizedString(@"Downloading %@ of %@ resources (%@ so far)…", @"Offline pack status: completed, expected, bytes"), completedString, expectedString, byteCountString]; break; @@ -247,12 +247,12 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac NSError *error = notification.userInfo[MGLOfflinePackErrorUserInfoKey]; NSAssert([error isKindOfClass:[NSError class]], @"MGLOfflineStorage notification has a non-error error."); - NSString *message = [NSString stringWithFormat:@"iosapp encountered an error while downloading the offline pack “%@”: %@", pack.name, error.localizedFailureReason]; + NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Mapbox GL encountered an error while downloading the offline pack “%@”: %@", @"Error message: name, reason"), pack.name, error.localizedFailureReason]; if (error.code == MGLErrorCodeConnectionFailed) { NSLog(@"%@", message); } else { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Error Downloading Offline Pack" message:message preferredStyle:UIAlertControllerStyleAlert]; - [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Error Downloading Offline Pack", @"Error title") message:message preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"") style:UIAlertActionStyleDefault handler:nil]]; [self presentViewController:alertController animated:YES completion:nil]; } } diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index f6e0cc0ae8..9df38a0847 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -10,8 +10,6 @@ #import <OpenGLES/ES2/gl.h> #import <objc/runtime.h> -static NSString * const kCustomCalloutTitle = @"Custom Callout"; - static const CLLocationCoordinate2D WorldTourDestinations[] = { { .latitude = 38.9131982, .longitude = -77.0325453144239 }, { .latitude = 37.7757368, .longitude = -122.4135302 }, @@ -19,6 +17,18 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { { .latitude = -13.15589555, .longitude = -74.2178961777998 }, }; +@interface MBXDroppedPinAnnotation : MGLPointAnnotation +@end + +@implementation MBXDroppedPinAnnotation +@end + +@interface MBXCustomCalloutAnnotation : MGLPointAnnotation +@end + +@implementation MBXCustomCalloutAnnotation +@end + @interface MBXViewController () <UIActionSheetDelegate, MGLMapViewDelegate> @property (nonatomic) IBOutlet MGLMapView *mapView; @@ -68,7 +78,7 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { } else { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Access Token" message:@"Enter your Mapbox access token to load Mapbox-hosted tiles and styles:" preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Access Token", @"Title of the access token prompt") message:NSLocalizedString(@"Enter your Mapbox access token to load Mapbox-hosted tiles and styles:", @"Message of the access token prompt") preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.keyboardType = UIKeyboardTypeURL; @@ -76,8 +86,8 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { textField.autocapitalizationType = UITextAutocapitalizationTypeNone; }]; - [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; - UIAlertAction *OKAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) + [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"") style:UIAlertActionStyleCancel handler:nil]]; + UIAlertAction *OKAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { UITextField *textField = alertController.textFields.firstObject; NSString *accessToken = textField.text; @@ -150,37 +160,37 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { - (IBAction)showSettings:(__unused id)sender { MGLMapDebugMaskOptions debugMask = self.mapView.debugMask; - UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Map Settings" + UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Map Settings", @"Title of the settings action sheet") delegate:self - cancelButtonTitle:@"Cancel" + cancelButtonTitle:NSLocalizedString(@"Cancel", @"") destructiveButtonTitle:nil otherButtonTitles: - @"Reset Position", - ((debugMask & MGLMapDebugTileBoundariesMask) - ? @"Hide Tile Boundaries" - : @"Show Tile Boundaries"), - ((debugMask & MGLMapDebugTileInfoMask) - ? @"Hide Tile Info" - : @"Show Tile Info"), - ((debugMask & MGLMapDebugTimestampsMask) - ? @"Hide Tile Timestamps" - : @"Show Tile Timestamps"), - ((debugMask & MGLMapDebugCollisionBoxesMask) - ? @"Hide Collision Boxes" - : @"Show Collision Boxes"), - @"Add 100 Points", - @"Add 1,000 Points", - @"Add 10,000 Points", - @"Add Test Shapes", - @"Start World Tour", - @"Add Custom Callout Point", - @"Remove Annotations", - (_isShowingCustomStyleLayer - ? @"Hide Custom Style Layer" - : @"Show Custom Style Layer"), - @"Print Telemetry Logfile", - @"Delete Telemetry Logfile", - nil]; + NSLocalizedString(@"Reset Position", @"Action in the settings action sheet"), + ((debugMask & MGLMapDebugTileBoundariesMask) + ? NSLocalizedString(@"Hide Tile Boundaries", @"Action in the settings action sheet") + : NSLocalizedString(@"Show Tile Boundaries", @"Action in the settings action sheet")), + ((debugMask & MGLMapDebugTileInfoMask) + ? NSLocalizedString(@"Hide Tile Info", @"Action in the settings action sheet") + : NSLocalizedString(@"Show Tile Info", @"Action in the settings action sheet")), + ((debugMask & MGLMapDebugTimestampsMask) + ? NSLocalizedString(@"Hide Tile Timestamps", @"Action in the settings action sheet") + : NSLocalizedString(@"Show Tile Timestamps", @"Action in the settings action sheet")), + ((debugMask & MGLMapDebugCollisionBoxesMask) + ? NSLocalizedString(@"Hide Collision Boxes", @"Action in the settings action sheet") + : NSLocalizedString(@"Show Collision Boxes", @"Action in the settings action sheet")), + NSLocalizedString(@"Add 100 Points", @"Action in the settings action sheet"), + NSLocalizedString(@"Add 1,000 Points", @"Action in the settings action sheet"), + NSLocalizedString(@"Add 10,000 Points", @"Action in the settings action sheet"), + NSLocalizedString(@"Add Test Shapes", @"Action in the settings action sheet"), + NSLocalizedString(@"Start World Tour", @"Action in the settings action sheet"), + NSLocalizedString(@"Add Custom Callout Point", @"Action in the settings action sheet"), + NSLocalizedString(@"Remove Annotations", @"Action in the settings action sheet"), + (_isShowingCustomStyleLayer + ? NSLocalizedString(@"Hide Custom Style Layer", @"Action in the settings action sheet") + : NSLocalizedString(@"Show Custom Style Layer", @"Action in the settings action sheet")), + NSLocalizedString(@"Print Telemetry Logfile", @"Action in the settings action sheet"), + NSLocalizedString(@"Delete Telemetry Logfile", @"Action in the settings action sheet"), + nil]; [sheet showFromBarButtonItem:self.navigationItem.leftBarButtonItem animated:YES]; } @@ -434,9 +444,9 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { { [self.mapView removeAnnotations:self.mapView.annotations]; - MGLPointAnnotation *annotation = [MGLPointAnnotation new]; + MBXCustomCalloutAnnotation *annotation = [[MBXCustomCalloutAnnotation alloc] init]; annotation.coordinate = CLLocationCoordinate2DMake(48.8533940, 2.3775439); - annotation.title = kCustomCalloutTitle; + annotation.title = NSLocalizedString(@"Custom Callout", @"Title of a custom callout view"); [self.mapView addAnnotation:annotation]; [self.mapView showAnnotations:@[annotation] animated:YES]; @@ -446,10 +456,10 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { { if (longPress.state == UIGestureRecognizerStateBegan) { - MGLPointAnnotation *point = [MGLPointAnnotation new]; + MBXDroppedPinAnnotation *point = [[MBXDroppedPinAnnotation alloc] init]; point.coordinate = [self.mapView convertPoint:[longPress locationInView:longPress.view] toCoordinateFromView:self.mapView]; - point.title = @"Dropped Marker"; + point.title = NSLocalizedString(@"Dropped Pin", @"Title of a dropped pin annotation"); point.subtitle = [[[MGLCoordinateFormatter alloc] init] stringFromCoordinate:point.coordinate]; [self.mapView addAnnotation:point]; [self.mapView selectAnnotation:point animated:YES]; @@ -464,12 +474,12 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ styleNames = @[ - @"Streets", - @"Emerald", - @"Light", - @"Dark", - @"Satellite", - @"Hybrid", + NSLocalizedString(@"Streets", @"Style name"), + NSLocalizedString(@"Emerald", @"Style name"), + NSLocalizedString(@"Light", @"Style name"), + NSLocalizedString(@"Dark", @"Style name"), + NSLocalizedString(@"Satellite", @"Style name"), + NSLocalizedString(@"Hybrid", @"Style name"), ]; styleURLs = @[ [MGLStyle streetsStyleURL], @@ -594,8 +604,8 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { - (MGLAnnotationImage *)mapView:(MGLMapView * __nonnull)mapView imageForAnnotation:(id <MGLAnnotation> __nonnull)annotation { - if ([annotation.title isEqualToString:@"Dropped Marker"] - || [annotation.title isEqualToString:kCustomCalloutTitle]) + if ([annotation isKindOfClass:[MBXDroppedPinAnnotation class]] + || [annotation isKindOfClass:[MBXCustomCalloutAnnotation class]]) { return nil; // use default marker } @@ -707,7 +717,7 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { break; case MGLUserTrackingModeFollowWithCourse: newButtonImage = nil; - newButtonTitle = @"Course"; + newButtonTitle = NSLocalizedString(@"Course", @"User tracking mode"); break; } @@ -720,7 +730,7 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = { - (UIView<MGLCalloutView> *)mapView:(__unused MGLMapView *)mapView calloutViewForAnnotation:(id<MGLAnnotation>)annotation { if ([annotation respondsToSelector:@selector(title)] - && [annotation.title isEqualToString:kCustomCalloutTitle]) + && [annotation isKindOfClass:[MBXCustomCalloutAnnotation class]]) { MBXCustomCalloutView *calloutView = [[MBXCustomCalloutView alloc] init]; calloutView.representedObject = annotation; diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index c7367a68a0..fc5ece03c7 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -134,6 +134,8 @@ DA88488C1CBB037E00AB86E3 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */; }; DA88488E1CBB047F00AB86E3 /* reachability.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88488D1CBB047F00AB86E3 /* reachability.h */; }; DA8848901CBB048E00AB86E3 /* reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488F1CBB048E00AB86E3 /* reachability.m */; }; + DA89632B1CC4E66500684375 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA8963291CC4E66500684375 /* Localizable.strings */; }; + DA89632F1CC4EE3300684375 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA89632C1CC4ECD300684375 /* Localizable.strings */; }; DA8963371CC549A100684375 /* glyphs in Resources */ = {isa = PBXBuildFile; fileRef = DA8963331CC549A100684375 /* glyphs */; }; DA8963381CC549A100684375 /* sprites in Resources */ = {isa = PBXBuildFile; fileRef = DA8963341CC549A100684375 /* sprites */; }; DA8963391CC549A100684375 /* styles in Resources */ = {isa = PBXBuildFile; fileRef = DA8963351CC549A100684375 /* styles */; }; @@ -387,6 +389,8 @@ DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMCalloutView.m; sourceTree = "<group>"; }; DA88488D1CBB047F00AB86E3 /* reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reachability.h; path = ../../include/mbgl/platform/darwin/reachability.h; sourceTree = "<group>"; }; DA88488F1CBB048E00AB86E3 /* reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = reachability.m; path = src/reachability.m; sourceTree = "<group>"; }; + DA89632A1CC4E66500684375 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; }; + DA89632D1CC4ECD300684375 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; }; DA8963331CC549A100684375 /* glyphs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = glyphs; sourceTree = "<group>"; }; DA8963341CC549A100684375 /* sprites */ = {isa = PBXFileReference; lastKnownFileType = folder; path = sprites; sourceTree = "<group>"; }; DA8963351CC549A100684375 /* styles */ = {isa = PBXFileReference; lastKnownFileType = folder; path = styles; sourceTree = "<group>"; }; @@ -497,6 +501,7 @@ DA1DC9561CB6C1C2006E619F /* Main.storyboard */, DA1DC95B1CB6C1C2006E619F /* LaunchScreen.storyboard */, DA1DC99E1CB6E088006E619F /* Assets.xcassets */, + DA8963291CC4E66500684375 /* Localizable.strings */, DA1DC96C1CB6C6CE006E619F /* points.geojson */, DA1DC96D1CB6C6CE006E619F /* polyline.geojson */, DA1DC96F1CB6C6CE006E619F /* threestates.geojson */, @@ -655,6 +660,7 @@ DA8848621CBAFCC100AB86E3 /* Resources */ = { isa = PBXGroup; children = ( + DA89632C1CC4ECD300684375 /* Localizable.strings */, DA8848771CBAFD5C00AB86E3 /* api_mapbox_com-digicert.der */, DA8848781CBAFD5C00AB86E3 /* api_mapbox_com-geotrust.der */, DA8848631CBAFCC100AB86E3 /* Compass.png */, @@ -1001,6 +1007,7 @@ DA4A26951CB6E337000B7809 /* LaunchScreen.storyboard in Resources */, DA1DC9701CB6C6CE006E619F /* points.geojson in Resources */, DA1DC9711CB6C6CE006E619F /* polyline.geojson in Resources */, + DA89632B1CC4E66500684375 /* Localizable.strings in Resources */, DA1DC99D1CB6E076006E619F /* Default-568h@2x.png in Resources */, DA1DC9731CB6C6CE006E619F /* threestates.geojson in Resources */, DA1DC99F1CB6E088006E619F /* Assets.xcassets in Resources */, @@ -1019,6 +1026,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + DA89632F1CC4EE3300684375 /* Localizable.strings in Resources */, DA8848731CBAFCC100AB86E3 /* mapbox.png in Resources */, DA8848741CBAFCC100AB86E3 /* mapbox@2x.png in Resources */, DA88487A1CBAFD5C00AB86E3 /* api_mapbox_com-digicert.der in Resources */, @@ -1199,6 +1207,22 @@ name = LaunchScreen.storyboard; sourceTree = "<group>"; }; + DA8963291CC4E66500684375 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + DA89632A1CC4E66500684375 /* Base */, + ); + name = Localizable.strings; + sourceTree = "<group>"; + }; + DA89632C1CC4ECD300684375 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + DA89632D1CC4ECD300684375 /* Base */, + ); + name = Localizable.strings; + sourceTree = "<group>"; + }; DABCABB81CB80692000A7C39 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( diff --git a/platform/ios/resources/Base.lproj/Localizable.strings b/platform/ios/resources/Base.lproj/Localizable.strings new file mode 100644 index 0000000000..b72bc21e63 --- /dev/null +++ b/platform/ios/resources/Base.lproj/Localizable.strings @@ -0,0 +1,75 @@ +/* Accessibility label */ +"Attribution info" = "Attribution info"; + +/* No comment provided by engineer. */ +"Cancel" = "Cancel"; + +/* Accessibility label */ +"Compass" = "Compass"; + +/* Telemetry prompt button */ +"Don’t Participate" = "Don’t Participate"; + +/* Action in attribution sheet */ +"Improve This Map" = "Improve This Map"; + +/* Telemetry prompt button */ +"Keep Participating" = "Keep Participating"; + +/* Telemetry prompt title */ +"Make Mapbox Maps Better" = "Make Mapbox Maps Better"; + +/* Accessibility label */ +"Map" = "Map"; + +/* Action sheet title */ +"Mapbox iOS SDK" = "Mapbox iOS SDK"; + +/* Accessibility label */ +"Mapbox logo" = "Mapbox logo"; + +/* Action in attribution sheet */ +"Mapbox Telemetry" = "Mapbox Telemetry"; + +/* Setup documentation URL display string */ +"mapbox.com/help/first-steps-ios-sdk" = "mapbox.com/help/first-steps-ios-sdk"; + +/* Compass abbreviation for north */ +"N" = "N"; + +/* Telemetry prompt button */ +"Participate" = "Participate"; + +/* Telemetry prompt button */ +"Stop Participating" = "Stop Participating"; + +/* Telemetry prompt button */ +"Tell Me More" = "Tell Me More"; + +/* No comment provided by engineer. */ +"The session data task failed. Original request was: %@" = "The session data task failed. Original request was: %@"; + +/* No comment provided by engineer. */ +"The status code was %ld" = "The status code was %ld"; + +/* Instructions in Interface Builder designable; property list dictionary key, file name */ +"To display a Mapbox-hosted map here, set %@ to your access token in %@\n\nFor detailed instructions, see:" = "To display a Mapbox-hosted map here, set %1$@ to your access token in %2$@\n\nFor detailed instructions, see:"; + +/* Accessibility label */ +"User location" = "User location"; + +/* Telemetry prompt message */ +"You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data." = "You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; + +/* Default user location annotation title */ +"You Are Here" = "You Are Here"; + +/* Telemetry prompt message */ +"You can help make OpenStreetMap and Mapbox maps better by contributing anonymous usage data." = "You can help make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; + +/* Action in attribution sheet */ +"© Mapbox" = "© Mapbox"; + +/* Action in attribution sheet */ +"© OpenStreetMap" = "© OpenStreetMap"; + diff --git a/platform/ios/resources/Compass.png b/platform/ios/resources/Compass.png Binary files differindex e6b0b52c58..08bed0591b 100644 --- a/platform/ios/resources/Compass.png +++ b/platform/ios/resources/Compass.png diff --git a/platform/ios/resources/Compass@2x.png b/platform/ios/resources/Compass@2x.png Binary files differindex 2bd8a286da..8473a2d1ec 100644 --- a/platform/ios/resources/Compass@2x.png +++ b/platform/ios/resources/Compass@2x.png diff --git a/platform/ios/resources/Compass@3x.png b/platform/ios/resources/Compass@3x.png Binary files differindex 9308a46a51..9cf66ca483 100644 --- a/platform/ios/resources/Compass@3x.png +++ b/platform/ios/resources/Compass@3x.png diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 9f982f7843..9290a00fa9 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -27,9 +27,9 @@ #include <mbgl/util/chrono.hpp> #import "Mapbox.h" -#import "../../darwin/src/MGLGeometry_Private.h" -#import "../../darwin/src/MGLMultiPoint_Private.h" -#import "../../darwin/src/MGLOfflineStorage_Private.h" +#import "MGLGeometry_Private.h" +#import "MGLMultiPoint_Private.h" +#import "MGLOfflineStorage_Private.h" #import "NSBundle+MGLAdditions.h" #import "NSString+MGLAdditions.h" @@ -59,8 +59,6 @@ typedef NS_ENUM(NSUInteger, MGLUserTrackingState) { MGLUserTrackingStateChanged, }; -NSString *const MGLMapboxSetupDocumentationURLDisplayString = @"mapbox.com/help/first-steps-ios-sdk"; - const NSTimeInterval MGLAnimationDuration = 0.3; /// Duration of an animation due to a user location update, typically chosen to @@ -305,7 +303,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) [self createGLView]; } - self.accessibilityLabel = @"Map"; + self.accessibilityLabel = NSLocalizedString(@"Map", @"Accessibility label"); self.backgroundColor = [UIColor clearColor]; self.clipsToBounds = YES; @@ -350,7 +348,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // UIImage *logo = [[MGLMapView resourceImageNamed:@"mapbox.png"] imageWithAlignmentRectInsets:UIEdgeInsetsMake(1.5, 4, 3.5, 2)]; _logoView = [[UIImageView alloc] initWithImage:logo]; - _logoView.accessibilityLabel = @"Mapbox logo"; + _logoView.accessibilityLabel = NSLocalizedString(@"Mapbox logo", @"Accessibility label"); _logoView.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_logoView]; _logoViewConstraints = [NSMutableArray array]; @@ -358,7 +356,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // setup attribution // _attributionButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; - _attributionButton.accessibilityLabel = @"Attribution info"; + _attributionButton.accessibilityLabel = NSLocalizedString(@"Attribution info", @"Accessibility label"); [_attributionButton addTarget:self action:@selector(showAttribution) forControlEvents:UIControlEventTouchUpInside]; _attributionButton.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_attributionButton]; @@ -367,8 +365,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // setup compass // - _compassView = [[UIImageView alloc] initWithImage:[MGLMapView resourceImageNamed:@"Compass.png"]]; - _compassView.accessibilityLabel = @"Compass"; + _compassView = [[UIImageView alloc] initWithImage:self.compassImage]; + _compassView.accessibilityLabel = NSLocalizedString(@"Compass", @"Accessibility label"); _compassView.frame = CGRectMake(0, 0, _compassView.image.size.width, _compassView.image.size.height); _compassView.alpha = 0; _compassView.userInteractionEnabled = YES; @@ -493,6 +491,26 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) }); } +- (UIImage *)compassImage +{ + UIImage *scaleImage = [MGLMapView resourceImageNamed:@"Compass.png"]; + UIGraphicsBeginImageContextWithOptions(scaleImage.size, NO, [UIScreen mainScreen].scale); + [scaleImage drawInRect:{ CGPointZero, scaleImage.size }]; + + NSAttributedString *north = [[NSAttributedString alloc] initWithString:NSLocalizedString(@"N", @"Compass abbreviation for north") attributes:@{ + NSFontAttributeName: [UIFont systemFontOfSize:9 weight:UIFontWeightUltraLight], + NSForegroundColorAttributeName: [UIColor whiteColor], + }]; + CGRect stringRect = CGRectMake((scaleImage.size.width - north.size.width) / 2, + scaleImage.size.height * 0.45, + north.size.width, north.size.height); + [north drawInRect:stringRect]; + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return image; +} + - (void)reachabilityChanged:(NSNotification *)notification { MGLReachability *reachability = [notification object]; @@ -1518,15 +1536,15 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { if ( ! self.attributionSheet) { - self.attributionSheet = [[UIActionSheet alloc] initWithTitle:@"Mapbox iOS SDK" + self.attributionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Mapbox iOS SDK", @"Action sheet title") delegate:self - cancelButtonTitle:@"Cancel" + cancelButtonTitle:NSLocalizedString(@"Cancel", @"") destructiveButtonTitle:nil otherButtonTitles: - @"© Mapbox", - @"© OpenStreetMap", - @"Improve This Map", - @"Mapbox Telemetry", + NSLocalizedString(@"© Mapbox", @"Action in attribution sheet"), + NSLocalizedString(@"© OpenStreetMap", @"Action in attribution sheet"), + NSLocalizedString(@"Improve This Map", @"Action in attribution sheet"), + NSLocalizedString(@"Mapbox Telemetry", @"Action in attribution sheet"), nil]; } @@ -1561,22 +1579,22 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) if ([[NSUserDefaults standardUserDefaults] boolForKey:@"MGLMapboxMetricsEnabled"]) { - message = @"You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; - participate = @"Keep Participating"; - optOut = @"Stop Participating"; + message = NSLocalizedString(@"You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data.", @"Telemetry prompt message"); + participate = NSLocalizedString(@"Keep Participating", @"Telemetry prompt button"); + optOut = NSLocalizedString(@"Stop Participating", @"Telemetry prompt button"); } else { - message = @"You can help make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; - participate = @"Participate"; - optOut = @"Don’t Participate"; + message = NSLocalizedString(@"You can help make OpenStreetMap and Mapbox maps better by contributing anonymous usage data.", @"Telemetry prompt message"); + participate = NSLocalizedString(@"Participate", @"Telemetry prompt button"); + optOut = NSLocalizedString(@"Don’t Participate", @"Telemetry prompt button"); } - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Make Mapbox Maps Better" + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Make Mapbox Maps Better", @"Telemetry prompt title") message:message delegate:self cancelButtonTitle:participate - otherButtonTitles:@"Tell Me More", optOut, nil]; + otherButtonTitles:NSLocalizedString(@"Tell Me More", @"Telemetry prompt button"), optOut, nil]; [alert show]; } } @@ -1590,7 +1608,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) else if (buttonIndex == alertView.firstOtherButtonIndex) { [[UIApplication sharedApplication] openURL: - [NSURL URLWithString:@"https://mapbox.com/telemetry/"]]; + [NSURL URLWithString:@"https://www.mapbox.com/telemetry/"]]; } else if (buttonIndex == alertView.firstOtherButtonIndex + 1) { @@ -4042,7 +4060,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // Headline UILabel *headlineLabel = [[UILabel alloc] init]; - headlineLabel.text = @"MGLMapView"; + headlineLabel.text = NSStringFromClass([self class]); headlineLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; headlineLabel.textAlignment = NSTextAlignmentCenter; headlineLabel.numberOfLines = 1; @@ -4053,8 +4071,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // Explanation UILabel *explanationLabel = [[UILabel alloc] init]; - explanationLabel.text = (@"To display a Mapbox-hosted map here, set MGLMapboxAccessToken to your access token in Info.plist\n\n" - @"For detailed instructions, see:"); + explanationLabel.text = [NSString stringWithFormat:NSLocalizedString(@"To display a Mapbox-hosted map here, set %@ to your access token in %@\n\nFor detailed instructions, see:", @"Instructions in Interface Builder designable; property list dictionary key, file name"), @"MGLMapboxAccessToken", @"Info.plist"]; explanationLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; explanationLabel.numberOfLines = 0; explanationLabel.translatesAutoresizingMaskIntoConstraints = NO; @@ -4064,7 +4081,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // Link UIButton *linkButton = [UIButton buttonWithType:UIButtonTypeSystem]; - [linkButton setTitle:MGLMapboxSetupDocumentationURLDisplayString forState:UIControlStateNormal]; + [linkButton setTitle:NSLocalizedString(@"mapbox.com/help/first-steps-ios-sdk", @"Setup documentation URL display string") forState:UIControlStateNormal]; linkButton.translatesAutoresizingMaskIntoConstraints = NO; linkButton.titleLabel.numberOfLines = 0; [linkButton setContentCompressionResistancePriority:UILayoutPriorityDefaultLow diff --git a/platform/ios/src/MGLUserLocation.m b/platform/ios/src/MGLUserLocation.m index 0ee90a3c2c..72acb6db97 100644 --- a/platform/ios/src/MGLUserLocation.m +++ b/platform/ios/src/MGLUserLocation.m @@ -1,6 +1,7 @@ #import "MGLUserLocation_Private.h" #import "MGLMapView.h" +#import "NSBundle+MGLAdditions.h" NS_ASSUME_NONNULL_BEGIN @@ -68,7 +69,7 @@ NS_ASSUME_NONNULL_END - (NSString *)title { - return (_title ? _title : @"You Are Here"); + return _title ?: NSLocalizedString(@"You Are Here", @"Default user location annotation title"); } - (NSString *)description diff --git a/platform/ios/src/MGLUserLocationAnnotationView.m b/platform/ios/src/MGLUserLocationAnnotationView.m index ac8dd0790b..d0497416b8 100644 --- a/platform/ios/src/MGLUserLocationAnnotationView.m +++ b/platform/ios/src/MGLUserLocationAnnotationView.m @@ -4,6 +4,7 @@ #import "MGLUserLocation_Private.h" #import "MGLAnnotation.h" #import "MGLMapView.h" +#import "NSBundle+MGLAdditions.h" const CGFloat MGLUserLocationAnnotationDotSize = 22.0; const CGFloat MGLUserLocationAnnotationHaloSize = 115.0; @@ -53,7 +54,7 @@ const CGFloat MGLUserLocationAnnotationArrowSize = MGLUserLocationAnnotationPuck self.annotation = [[MGLUserLocation alloc] initWithMapView:mapView]; _mapView = mapView; [self setupLayers]; - self.accessibilityLabel = @"User location"; + self.accessibilityLabel = NSLocalizedString(@"User location", @"Accessibility label"); } return self; } |