Подтвердить что ты не робот

Локализация современного приложения Mac на основе xib

Наш - это приложение Mac с открытым исходным кодом, локализованное добровольцами. Эти добровольцы будут выполнять свою работу над специальными сборками локализации программного обеспечения (с незащищенными наконечниками), а затем отправить нам изменения для интеграции в исходные файлы xib и string.

Проблема заключается в том, что, хотя существует способ интегрировать изменения строк, не сдувая предыдущие изменения размера, я не вижу способа для интеграции новых изменений строки и размера (как при добавлении или замене представлений).

Единственный способ сделать то, что я вижу, - это заставить локализаторы работать непосредственно с исходными xib и отправлять нам diff. Это означает, что они должны загружать весь исходный код, а не только локализуемую версию выпуска, работать как в Xcode, так и в IB, и либо запускать команду diff (per xib), либо устанавливать и использовать Mercurial.

Есть ли лучший способ для приложения на основе xib?

4b9b3361

Ответ 1

UPDATE Январь 2014 года: код автоаудита Яблоков в сочетании с их базовыми материалами локализации взял на себя большинство моих идей и улучшил их. Я рекомендую не использовать мои старые инструменты, о которых я говорю в этом ответе. Но, также, человек был прав!


Я настоятельно настоятельно рекомендую против изменений рамки в локализации. Я знаю, что это противоречит советам Apple, но есть МНОГО проблем с разрешением изменений кадра - в итоге вы получаете миллиард краевых случаев.

Представьте, что в вашем приложении 10 XIB, и вы поддерживаете 12 языков. Теперь у вас есть 120 различных макетов. Вы просто не можете этого сделать.

Измените строки, оставьте виды, где они есть. Сделайте их больше на всех языках, если вам нужно. Похоже, это не должно работать, но это так. (Я выиграл три награды Apple Design Awards с приложением, которое локализовано в 10 или около того таким образом.)

Особенности:

  • Для радио и флажков просто позвольте им простираться вправо, за пределами последнего английского символа. Это также обеспечивает хорошую большую зону приземления для неточных мышелов.

  • Для кнопок они должны быть широкими в любом случае, потому что никогда не выглядит хорошо, если текст находится в середине кнопок.

  • Для заголовков в столбцах tableview вы должны авторизоваться при загрузке em, если это необходимо.

  • Для пояснительного текста вы должны иметь дополнительное пространство справа и, возможно, дополнительную строку. Это просто делает английскую версию XIB казаться менее загроможденной. Конечно, немцы собираются увидеть немного более жесткий XIB, но, эй, они немцы - они, вероятно, привыкли к этому. Вероятно, для этого есть даже немецкое слово. "Deutscheninterfakkenclutterlongen."

  • Если текстовое поле центрировано, просто добавьте равное пространство с обеих сторон. Нет причин не делать этого.

Я объединил это со сценариями, которые высасывают все строки из моих XIB и помещают их в файлы .strings, а затем динамически помещают строки во время выполнения, поэтому каждый может локализовать мое приложение без каких-либо специальных инструментов. Просто запустите кучу файлов .strings и запустите его!

Сообщение в блоге, включая полный источник: [Lost in Translations] ¹.

Ответ 2

Я признаюсь, что я не так хорошо знаком с процессом локализации приложений Mac. Но я столкнулся с script частью трехмерной библиотеки iPhone, которая, похоже, может быть полезна: diffstrings.py - это Python script, который "сравнивает ваш основной язык со всеми вашими другими локалями, чтобы помочь вам определить, какие новые строки необходимо перевести. который можно перевести, а затем объединить обратно в ваши файлы строк."

РЕДАКТИРОВАТЬ: В качестве помощника ответ Wil Shipley на этот вопрос, я добавлю ссылку на запись в блоге, которую он только что написал, которая более подробно описывает локализацию и предоставляет некоторые из инструментов, которые он создал для облегчения процесса.

Ответ 3

Где я работал, у нас тоже была эта проблема. Наше приложение транслировалось на 10 разных языков.

Сначала мы попытались сделать то, что предложил Виль, чтобы сделать все супер широкое и соответствовать всем языкам. К сожалению, "онлайн-резервное копирование" может быть довольно коротким на английском, но на других языках (особенно на испанском), это действительно долго ( "copia de seguridad" просто означает "резервное копирование" ). Расширение нашего пользовательского интерфейса заставило все выглядеть довольно ужасно.

В один прекрасный день я играл с некоторыми материалами Core Animation и обнаружил класс CAConstraint. CAConstraint - это в основном способ определения отношения компоновки между двумя CALayers. Вы даете одному слою имя (например, "layerA" ), а затем говорите, что "layerB ограничен [таким-то образом]] для слоя-брата, называемого layerA". Затем, когда слой с именем layerA перемещается или изменяется, автоматически перемещается layerB. Это действительно опрятно, и это именно то, что мы искали.

После нескольких дней работы я придумал, что сейчас CHLayoutManager. Это в основном перезапись CAConstraint и друзей, но для NSViews. Вот простой пример того, как он работает:

CHLayoutConstraint * centerHorizontal = [CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMidX relativeTo:@"superview" attribute:CHLayoutConstraintAttributeMidX];
CHLayoutConstraint * centerVertical = [CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMidY relativeTo:@"superview" attribute:CHLayoutConstraintAttributeMidY];
[aView addConstraint:centerHorizontal];
[aView addConstraint:centerVertical];

Это сохранит aView с центром в сводке, независимо от того, как изменяется размер супервизора. Здесь другое:

[button1 setLayoutName:@"button1"];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMinX relativeTo:@"button1" attribute:CHLayoutConstraintAttributeMaxX]];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMaxY relativeTo:@"button1" attribute:CHLayoutConstraintAttributeMaxY]];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeWidth relativeTo:@"button1" attribute:CHLayoutConstraintAttributeWidth]];

Это сохранит button2 привязан к правому краю button1, а также сохранит button2 положение и ширину Y так же, как button1.

Внутри CHLayoutManager используется NSValueTransformer для вычисления новой информации о местоположении. Некоторые инициализаторы CHLayoutConstraint принимают NSValueTransformer, поэтому вы можете создавать произвольно сложные макеты.

Мы использовали это для ограничения и выделения всего пользовательского интерфейса, а затем выполнили всю локализацию в коде (и впоследствии вызывали -sizeToFit с некоторыми изменениями). Наш пользовательский интерфейс просто впишется в его окончательный формат. Это оказалось очень удобно. Мы просто упаковываем наши файлы .strings, отправляем их переводчикам, а затем оставляем их на место, когда мы их возвращаем, и наше приложение будет немедленно локализовано для этого языка.

CHLayoutManager не является совершенным. Он не разрешает конфликты, а просто применяет ограничения в том порядке, в котором они добавлены. Таким образом, вы можете ограничить (например) MinX вид 42 различными способами, но будет использоваться только последний. Кроме того, если вы ограничиваете MinX и MaxX, они также будут применяться в том порядке, в котором они будут добавлены, и не будут растягивать или уменьшать ширину. Другими словами, ограничение одного атрибута представления не повлияет на другие атрибуты. Он совместим с 10.5+ (GC и non). Однако из-за некоторых изменений в Lion маловероятно, что я рассмотрю недостатки.

Несмотря на эти недостатки, это чрезвычайно гибкая структура и (IMO) довольно красивый код. (Плюс, я swizzle -[NSView dealloc]! Yay!)


Update

Теперь, когда AppKit имеет такую ​​же функциональность (через NSLayoutConstraint), я рекомендую использовать эту систему вместо CHLayoutManager. Он гораздо более надежный.

Ответ 4

Имейте в виду, что XIB файлы - это просто файлы XML в неясном формате, поэтому вы можете легко их перевести, при условии, что вы можете найти, какие строки там есть для перевода в первую очередь. Например, здесь фрагмент, создающий кнопку под названием Jenson:

<object class="NSButtonCell" key="NSCell" id="41219959">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Jenson</string>
...
</object>

Итак, вы можете перевести эту строку, а затем заменить ее в XIB своим переведенным значением. Чтобы убедиться, что он работает как ожидалось, вы можете изменить язык, чтобы вместо него использовать случайные ключи (например, BUTTON_TITLE), что облегчит определение места, когда он отсутствует.

Однако позиции/размеры элементов фиксированы, поэтому вы можете иметь заголовки, которые переполняют пространство, заданное на другом языке. Это одна из причин, по которой у Mac есть отдельные файлы XIB для каждого языка, чтобы можно было внести корректировки на основе языка по языку, однако их трудно поддерживать.