Локализация в Xamarin.iOS
В этом документе рассматриваются функции локализации пакета SDK для iOS и способы доступа к ним с помощью Xamarin.
Сведения о кодировках internationalization см. в инструкциях по включению наборов символов и кодовых страниц в приложениях, которые должны обрабатывать данные, отличные от Юникода.
Функции платформы iOS
В этом разделе описаны некоторые функции локализации в iOS. Перейдите к следующему разделу , чтобы просмотреть конкретный код и примеры.
Язык
Пользователи выбирают язык в приложении Параметры. Этот параметр влияет на строки языка и изображения, отображаемые операционной системой и в приложениях.
Чтобы определить язык, используемый в приложении, получите первый элемент NSBundle.MainBundle.PreferredLocalizations
:
var lang = NSBundle.MainBundle.PreferredLocalizations[0];
Это значение будет языковым кодом, например en
для английского языка, es
для испанского языка, ja
для японского языка и т. д. Возвращаемое значение ограничено одной из локализаций, поддерживаемых приложением (используя резервные правила для определения оптимального соответствия).
Код приложения не всегда должен проверка для этого значения— Xamarin и iOS предоставляют функции, которые помогают автоматически предоставлять правильную строку или ресурс для языка пользователя. Эти функции описаны в оставшейся части этого документа.
Примечание.
Используется NSLocale.PreferredLanguages
для определения языковых настроек пользователя независимо от локализаций, поддерживаемых приложением. Значения, возвращаемые этим методом, изменились в iOS 9; Дополнительные сведения см. в техническом примечание TN2418 .
Локаль
Пользователи выбирают языковой стандарт в приложении Параметры. Этот параметр влияет на формат дат, времени, чисел и валют.
Это позволяет пользователям выбирать, отображаются ли 12-часовые или 24-часовые форматы времени, независимо от того, является ли их десятичный разделитель запятыми или точкой, а также порядок дня, месяца и года в дате.
С помощью Xamarin у вас есть доступ к классам iOS () Apple,NSNumberFormatter
а также классам .NET в System.Globalization. Разработчики должны оценить, что лучше подходит для своих потребностей, так как в каждом из них доступны различные функции. В частности, если вы извлеките и отображаете цены на покупку в приложении с помощью StoreKit, следует использовать классы форматирования Apple для возвращаемых ценовых сведений.
Текущий языковой стандарт можно запрашивать двумя способами:
NSLocale.CurrentLocale.LocaleIdentifier
NSLocale.AutoUpdatingCurrentLocale.LocaleIdentifier
Первое значение может кэшироваться операционной системой и поэтому может не всегда отражать выбранный пользователем языковой стандарт. Используйте второе значение для получения выбранного языкового стандарта.
Примечание.
Mono (среда выполнения .NET, на которой основана Xamarin.iOS) и API iOS Apple не поддерживают идентичные наборы сочетаний языков и регионов. Из-за этого можно выбрать сочетание языка и региона в приложении iOS Параметры, которое не сопоставляется с допустимым значением в Mono. Например, установка языка i Телефон на английский язык и его регион в Испанию приведет к тому, что следующие API дают различные значения:
CurrentThead.CurrentCulture
: en-US (API Mono)CurrentThread.CurrentUICulture
: en-US (API Mono)NSLocale.CurrentLocale.LocaleIdentifier
: en_ES (API Apple)
Так как Mono используется CurrentThread.CurrentUICulture
для выбора ресурсов и CurrentThread.CurrentCulture
форматирования дат и валют, локализация на основе Mono (например, с RESX-файлами) может не дать ожидаемых результатов для этих сочетаний языков и регионов. В таких ситуациях следует использовать API Apple для локализации по мере необходимости.
NSCurrentLocaleDidChangeNotification
iOS создает экземпляр, когда пользователь обновляет языковой NSCurrentLocaleDidChangeNotification
стандарт. Приложения могут прослушивать это уведомление во время выполнения и вносить соответствующие изменения в пользовательский интерфейс.
Основы локализации в iOS
Следующие функции iOS легко используются в Xamarin для предоставления локализованных ресурсов для отображения пользователю. Ознакомьтесь с примером TaskyL10n, чтобы узнать, как реализовать эти идеи.
Указание языков по умолчанию и поддерживаемых языков в Info.plist
В technical Q&A QA1828: Как iOS определяет язык для вашего приложения, Apple описывает, как iOS выбирает язык для использования в приложении. Следующие факторы влияют на отображение языка:
- Предпочитаемые языки пользователя (найденные в приложении Параметры)
- Локализации, упакованные с приложением (папки LPROJ)
CFBundleDevelopmentRegion
(Значение Info.plist , указывающее язык по умолчанию для приложения)CFBundleLocalizations
(Массив Info.plist , указывающий все поддерживаемые локализации)
Как указано в Technical Q&A, CFBundleDevelopmentRegion
представляет регион и язык приложения по умолчанию. Если приложение явно не поддерживает какой-либо из предпочитаемых языков пользователя, он будет использовать язык, указанный в этом поле.
Внимание
IOS 11 применяет этот механизм выбора языка более строго, чем предыдущие версии операционной системы. Из-за этого любое приложение iOS 11, которое явно не объявляет поддерживаемые локализации, либо путем включения папок LPROJ или задания значения CFBundleLocalizations
для него, может отображаться другой язык в iOS 11, чем в iOS 10.
Если CFBundleDevelopmentRegion
в файле Info.plist не указано, средства сборки Xamarin.iOS в настоящее время используют значение en_US
по умолчанию. Хотя это может измениться в будущем выпуске, это означает, что язык по умолчанию является английским.
Чтобы убедиться, что приложение выбирает ожидаемый язык, выполните следующие действия:
- Укажите язык по умолчанию. Откройте Info.plist и используйте представление источника для
CFBundleDevelopmentRegion
задания значения ключа. В XML он должен выглядеть следующим образом:
<key>CFBundleDevelopmentRegion</key>
<string>es</string>
В этом примере используется "es", чтобы указать, что, если ни один из предпочитаемых языков пользователя не поддерживается, по умолчанию используется испанский язык.
- Объявите все поддерживаемые локализации. В Info.plist используйте представление источника, чтобы задать массив для
CFBundleLocalizations
ключа. В XML он должен выглядеть следующим образом:
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>es</string>
...
</array>
Приложения Xamarin.iOS, локализованные с помощью механизмов .NET, таких как RESX-файлы, также должны предоставлять эти значения Info.plist .
Дополнительные сведения об этих ключах Info.plist см. в справочнике по ключу списка свойств Apple.
Метод GetLocalizedString
Метод NSBundle.MainBundle.GetLocalizedString
ищет локализованный текст, хранящийся в файлах .strings в проекте. Эти файлы организованы по языку в специально именованных каталогах с суффиксом LPROJ (обратите внимание, что первая буква расширения — это строчная буква L).
Расположения файлов .strings
- Base.lproj — это каталог, содержащий ресурсы для языка по умолчанию. Он часто находится в корневом каталоге проекта (но также может размещаться в папке "Ресурсы ").
- <Каталоги language.lproj> создаются для каждого поддерживаемого языка, как правило, в папке "Ресурсы".
В каждом каталоге языка может быть несколько разных строковых файлов:
- Localizable.strings — основной список локализованного текста.
- InfoPlist.strings — определенные ключи в этом файле разрешены для перевода таких элементов, как имя приложения.
- <storyboard-name.strings> — необязательный файл, содержащий переводы элементов пользовательского интерфейса в раскадровке.
Действие сборки для этих файлов должно быть ресурсом пакета.
Формат файла .strings
Синтаксис локализованных строковых значений:
/* comment */
"key"="localized-value";
Следует экранировать следующие символы в строках:
- Цитата клиента (
\"
) \\
Обратной косой черты\n
Newline
Это пример es/Localizable.strings (ie). Испанский) файл из примера:
"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";
изображения;
Чтобы локализовать изображение в iOS, выполните приведенные ниже действия.
См. изображение в коде, например:
UIImage.FromBundle("flag");
Поместите файл образа по умолчанию flag.png в Base.lproj (каталог языка разработки на собственном языке).
При необходимости поместите локализованные версии образа в папки LPROJ для каждого языка (например, 1. es.lproj, ja.lproj). Используйте одно и то же имя файла, flag.png в каждом каталоге языка.
Если изображение не существует для определенного языка, iOS вернется к папке собственного языка по умолчанию и загружает изображение из нее.
Запуск образов
Используйте стандартные соглашения об именовании для образов запуска (и XIB или Storyboard для моделей i Телефон 6) при размещении их в каталогах LPROJ для каждого языка.
Default.png
Default@2x.png
Default-568h@2x.png
LaunchScreen.xib
Название приложения
Размещение файла InfoPlist.strings в каталоге lproj позволяет переопределить некоторые значения из списка Info.plist приложения, включая имя приложения:
"CFBundleDisplayName" = "LeónTodo";
Другие ключи, которые можно использовать для локализации строк для конкретного приложения:
- CFBundleName
- CFBundleShortVersionString
- NSHumanReadableCopyright
Дата и время
Хотя можно использовать встроенные функции даты и времени .NET (вместе с текущим CultureInfo
) для форматирования дат и времени для языкового стандарта, это будет игнорировать параметры пользователя для конкретного языкового стандарта (которые можно задать отдельно от языка).
Используйте iOS NSDateFormatter
для создания выходных данных, соответствующих предпочтениям языкового стандарта пользователя. В следующем примере кода показаны основные параметры форматирования даты и времени:
var date = NSDate.Now;
var df = new NSDateFormatter ();
df.DateStyle = NSDateFormatterStyle.Full;
df.TimeStyle = NSDateFormatterStyle.Long;
Debug.WriteLine ("Full,Long: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Short;
df.TimeStyle = NSDateFormatterStyle.Short;
Debug.WriteLine ("Short,Short: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Medium;
df.TimeStyle = NSDateFormatterStyle.None;
Debug.WriteLine ("Medium,None: " + df.StringFor(date));
Результаты для английского языка в США:
Full,Long: Friday, August 7, 2015 at 10:29:32 AM PDT
Short,Short: 8/7/15, 10:29 AM
Medium,None: Aug 7, 2015
Результаты для испанского языка в Испании:
Full,Long: viernes, 7 de agosto de 2015, 10:26:58 GMT-7
Short,Short: 7/8/15 10:26
Medium,None: 7/8/2015
Дополнительные сведения см. в документации По форматированию дат Apple. При тестировании форматирования даты и времени с учетом языкового стандарта проверка параметры языка и региона Телефон.
Макет справа налево (RTL)
IOS предоставляет ряд функций для создания приложений с поддержкой RTL:
- Используйте автоматические макеты
leading
иtrailing
атрибуты для выравнивания элементов управления (которые соответствуют левому и правому краю для английского языка, но обратно для языков RTL). ЭтотUIStackView
элемент управления особенно полезен для создания элементов управления с поддержкой RTL. - Используется
TextAlignment = UITextAlignment.Natural
для выравнивания текста (который будет оставлен для большинства языков, но справа для RTL). UINavigationController
автоматически переворачивает кнопку "Назад" и проводите пальцем по направлению.
На следующих снимках экрана показан локализованный пример задачи на арабском и иврите (хотя английский язык введен в полях):
iOS автоматически изменяет UINavigationController
и другие элементы управления помещаются внутри UIStackView
или выравниваются с автоматическим макетом.
Текст RTL локализован с помощью строковых файлов так же, как и текст LTR.
Локализация пользовательского интерфейса в коде
В примере tasky (локализованный в коде) показано, как локализовать приложение, в котором пользовательский интерфейс встроен в код (а не XIB или раскадровки).
Структура проекта
Файл Localizable.strings
Как описано выше, формат файла Localizable.strings состоит из пар "ключ-значение". Ключ описывает намерение строки, а значение — преобразованный текст, который будет использоваться в приложении.
Ниже показаны локализации испанского языка (es) для примера:
"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";
Выполнение локализации
В коде приложения, где установлен отображаемый текст пользовательского интерфейса (будь то текст метки или заполнитель входных данных и т. д.), код использует функцию iOS GetLocalizedString
для получения правильного перевода для отображения:
var localizedString = NSBundle.MainBundle.GetLocalizedString ("key", "optional");
someControl.Text = localizedString;
Локализация пользовательских интерфейсов раскадровки
В примере tasky (локализованная раскадровка) показано, как локализовать текст на элементах управления в раскадровки.
Структура проекта
Каталог Base.lproj содержит раскадровку, а также должен содержать изображения, используемые в приложении.
Другие каталоги языка содержат файл Localizable.strings для любых строковых ресурсов, на которые ссылается код, а также файл MainStoryboard.strings , содержащий переводы текста в раскадровки.
Каталоги языков должны содержать копию всех образов, локализованных, чтобы переопределить один из них в Base.lproj.
Идентификатор объекта / идентификатор локализации
При создании и редактировании элементов управления в раскадровки выберите каждый элемент управления и проверка идентификатор, используемый для локализации:
- В Visual Studio для Mac он расположен на панели свойств и называется идентификатором локализации.
- В Xcode он называется идентификатором объекта.
Это строковое значение часто имеет форму, например "NF3-h8-xmR", как показано на следующем снимке экрана:
Это значение используется в файле .strings для автоматического назначения переведенного текста каждому элементу управления.
MainStoryboard.strings
Формат файла перевода раскадровки аналогичен файлу Localizable.strings, за исключением того, что ключ (значение слева) не может быть определяемым пользователем, но вместо этого должен иметь очень конкретный формат: ObjectID.property
В примере Mainstoryboard.strings ниже можно увидеть placeholder
UITextField
текстовое свойство, которое можно локализовать; UILabel
s имеет text
свойство; и UIButton
текст по умолчанию задается с помощьюnormalTitle
:
"SXg-TT-IwM.placeholder" = "nombre de la tarea";
"Pqa-aa-ury.placeholder"= "otra información de tarea";
"zwR-D9-hM1.text" = "Detalles de la tarea";
"bAM-2j-Rzw.text" = "Notas"; /* Notes */
"NF3-h8-xmR.text" = "Completo"; /* Done */
"MWt-Ya-pMf.normalTitle" = "Guardar"; /* Save */
"IGr-pR-05L.normalTitle" = "Eliminar"; /* Delete */
Внимание
Использование раскадровки с классами размера может привести к переводам, которые не отображаются в приложении. Заметки о выпуске Xcode Apple указывают на то, что раскадровка или XIB не локализуется правильно, если три вещи верны: используется классы размера, базовая локализация и целевой объект сборки имеют значение Universal, а целевые объекты сборки — iOS 7.0. Исправление заключается в том, чтобы дублировать файл строк раскадровки в два идентичных файла: MainStoryboard~iphone.strings и MainStoryboard~ipad.strings, как показано на следующем снимке экрана:
Описание Магазина приложений
Следует часто задаваемые вопросы Apple по локализации App Store, чтобы ввести переводы для каждой страны, в которую ваше приложение находится в продаже. Обратите внимание, что переводы будут отображаться только в том случае, если приложение также содержит локализованный каталог LPROJ для языка.
Итоги
В этой статье рассматриваются основы локализации приложений iOS с помощью встроенных функций обработки ресурсов и раскадровки.
Дополнительные сведения о приложениях i18n и L10n для iOS, Android и кроссплатформенных приложений (включая Xamarin.Forms) см. в этом кроссплатформенной руководстве.