我们如何将Dodo Pizza应用程序翻译成阿拉伯语
#ios #swift #本地化 #rtl

您知道在iOS应用中添加右至左侧(RTL)语言的支持吗?您必须使用领导和尾随而不是左右,而且我们也不知道其他任何知识,但是我们必须使它困惑。

我们正在使Dodo Pizza应用程序准备在阿拉伯语中进行本地化。在本文中,我们想分享我们的发现,并告诉您,为什么我们需要在应用程序中需要RTL支持,为什么不足以调整代码中的布局以支持RTL,为什么我们必须重新绘制插图以及在什么阿拉伯百分比标志的方式与欧洲符号不同。此外,我们将显示许多屏幕截图,并将在代码中分享有关RTL支持的一些提示。

突发新闻!渡渡鸟已经打开了一个pizzeria in Dubai。对于开发人员而言,这意味着他们必须准备好在一个新国家 /地区启动的应用程序。这里工作的主要部分通常是针对后端开发人员,我们只需要在应用程序中添加一种新语言。

本地化已经建立了很长时间,但是迪拜的发布非常特别。迪拜的应用程序本地化与以前所有国家的本地化不同,因为阿拉伯语是从右到左写的。这意味着人们从右到左阅读。所有内容都从右到左感知。他们的凝视方向发生了变化。这意味着在应用程序中

Image description

首先,启用RTL

我们开始搜索了如何完成方法研究问题并搜索可能的解决方案。

苹果一开始就提供有关此主题的良好材料:

然后,我们决定自己获得RTL的感觉,然后开始戳我们的应用。如果您想查看启用RTL的应用程序将是什么样子,这就是您可以做到的:

Image description

在Xcode中转到编辑方案(选项+单击当前目标)'to Options Tab - 在App Language中选择左右pseudolanguage而不是系统语言 - 重新启动应用程序

在Xcode下拉菜单中,将有两个伪语言:左右向右直至左字符串。

第一个将简单地对齐右侧的应用程序的所有本地字符串。第二个将逆转字母。

Image description

请注意,如果您选择左转右字符串的权利,则只有本地字符串会更改。从后端发送的字符串将在发送时显示。

仅查看自己的应用程序是一个坏主意,因为您缺乏RTL-Apps的视觉体验。为了发展这项技能,我们研究了各种改编的应用程序和网站。

我们习惯了一些RTL并研究了应用程序中的所有内容后,我们开始起草所有屏幕屏幕截图的文档。我们对每个屏幕进行了两个屏幕截图(一个常规一个,一个带有启用RTL的屏幕),然后在每个屏幕上,我们描述了什么功能正常。当我们做到这一点时,我们意识到从屏幕到屏幕上反复出现了很多问题。我们将它们分组在一起。此外,我们将讨论每组问题。

Xcode与RTL-strings合作感到惊讶

奖金部分。检查一下,Xcode用RTL-strings做什么:

在视频中,我们总是按正确的箭头键。

为了进行比较,在Android Studio中,行为方式是完全不同的。在录音室中,光标始终朝着键盘上按箭头键的方向移动。也许可以在某个地方调整一下,但我们没有检查。

检查应用程序中有什么

让我们解决问题。

视图和单元格的布局

将应用程序调整为RTL语言时,iOS为我们完成了大部分工作。应用程序中有一些屏幕,可以在启用RTL时看起来像它们应有的方式。

当iOS无法正确逆转它们的方式时,

引起了一系列问题。

您必须转到每种观点,澄清为什么问题发生并手动修复。

例如,看看有效顺序的紫色小部件:

Image description

标题和主文本需要对准右侧;图片和主文字需要互换。

错误是什么:主动顺序的小部件是在不考虑RTL取向的框架上构成的。我们希望不使用帧上的布局,但是在这种情况下,这是对小部件的要求是合理的。

要正确显示小部件,您需要在属性视图的帮助下知道当前方向。

具有营养价值的视图和可以排除的成分完全混乱:

Image description

Image description

错误是什么:

  • 在营养价值中,所有标题都剩下的对齐,所有值都有正确的值。设置TextAlignment时,您需要考虑RTL;
  • 在成分视图中,按钮的关闭对齐=。left,并且成分列表在框架上布置。

RTL应用程序的改编已成为查看所有屏幕并确保所有使用的组件都与设计系统一致的一个很好的理由。因此,例如,我们完全更改了成分删除的对话。

结帐看起来也不很好:

Image description

错误是:看来屏幕完全没有秩序,但实际上一点也不是那么糟糕。只是乌拉贝尔(Uilabel)有一个错误的文字归因,而图片不反映。

在国家列表中,应首先显示国旗,然后显示该国的名称。这意味着,在RTL中,国旗应在该国的右边。

Image description

错误是:旗帜是表情符号。在代码中,就是这样:

var nameWithFlag: String {  
    "(isoCode.emoji) (name)"
}

注意按钮显示最近的比萨店:

Image description

错误是什么:该按钮在情节提要上的左右imageedgesets进行了硬编码。我们将它们更改为NSDirectionaledgeinsets,您可以将其设置为前进和落后插图,而不是左右。

除此之外,代码中还有很多地方有重复错误:

  • 对于Uilabel,它是设置的:textAlignment = .left或textAlignment = .right。根据场景,您必须根据有效的userinterinterfacelayoutdirection的价值使用textAlignment = .natural = .natural或设置文本签名。如果您使用。自然,如果为用户设置了LTR-取向,则文本将在左侧对齐,如果RTL向右对齐;
  • 在某些地方使用左右约束,而不是领先和尾随;
  • 在Pinlayout的帮助下,组成了几个屏幕,他们不支持RTL。

自定义UI元素

碰巧的是,开发人员已经做好了所有正确的操作:他们使用了领导和尾随,以便如果突然有RTL,一切都可以正常工作。在该项目的某些地方,我们面临着与之相关的错误。这就是电话号码输入领域发生的事情:

Image description

错误是什么:iOS正常运行 - 它自动逆转了电话号码输入的字段,因为我们在布局中使用了领先和尾随的约束。但是我们需要从左到右显示此字段,因为电话号码始终从左到右写入。最简单的方法是用semanticcontantentattribute = .forcelefttoright修复字段。

输入SMS代码的输入如何破裂很有趣。当您输入时,数字像往常一样出现(从左到右),但是背景中的点从右到左消失。在屏幕截图上,已经输入了3个数字,一个点仍然可见。

Image description

错误是:uistackView中包含的占位符点。启用RTL时,StackView会自动逆转,但是您还可以设置SemanticContentMode = .forceleftToright。

在半比萨饼中,圆形的滚动指示器已被镜像,现在它们位于披萨的中心:

Image description

错误是:滚动指标具有领导和落后的约束。 ios倒了。但是,对于RTL和LTR而言,用两半制成的披萨的屏幕是普遍的,这就是为什么不需要扭转其中的任何内容。我们将约束更改为左右。

在工具提示中,箭头应向左移动:

Image description

手动计算出箭头的sourcerect,从中绘制了箭头。现在,我们对LTR和RTL进行了不同的计算。

我们的分割control是自定义的。它看起来还不错,但是其中的片段必须更改位置。

Image description Image description

错误是什么:对于每个段,计算帧。我们添加了RTL的替代计算。

收藏

例如,某些收藏品(例如产品的浇头)没有镜像。在屏幕截图上,集合中的空插槽应在左下角,而不是右。

Image description

其他收藏集(例如,菜单中的类别)被镜像(它们在右边对齐)。但是其中的元素以错误的顺序显示。在屏幕截图上,披萨类别应为第一个,即最右边。

Image description

在屏幕上带有用于odocoins的产品,集合中的元素在正确的位置,但默认情况下是最后一个元素。在此系列中,第一类商品是饮料。如果您侧面滚动类别,则饮料将在正确的位置。

Image description

对于收集的所有问题,我们都有一个解决方案来使用支持RTL的UICollectionViewFlowLayout。为了镜像UICollectionViewFlowLayout,您需要创建一个从UicollectionViewFlowLayout继承的类,并重新定义Flipshorizo​​ntallizontallyInopPositElayOutDirection的属性。默认情况下,它是错误的,而必须为真。然后,将使用此布局收集。

class RTLSupportedCollectionViewFlowLayout: UICollectionViewFlowLayout {
    override var flipsHorizontallyInOppositeLayoutDirection: Bool {
        true
    }
}

有方向的图标

另一个主题是图片。其中一些必须镜像,其中一些不得。这是一门科学!

让我们查看输送方法选择的屏幕。由于图标显示了运动方向,因此应镜像第一个图标上的快递员。也就是说,快递员应该朝着用户走去,而不是远离他。

Image description

刀和叉子不需要镜像。我们在阿拉伯国家检查了他们右手握着刀。

在下一个屏幕截图上,靠近送货地址,箭头没有逆转。它需要逆转。

Image description

小部件上的星星也需要逆转,因为选择阿拉伯语的人将从右到左侧看小部件。恒星应以脸部而不是背部符合用户的视图。

这是一张受版权保护的照片,因此无需扭转披萨。摄影师创造了一个构图之类的东西。这样的照片应像它们一样留下。

在此阶段,有必要查看应用程序中的每张图片,并决定是否需要逆转。

对于需要倒转的图标,您可以设置一个特殊设置:

let image = UIImage(named: "some-image")
imageView.image = image?.imageFlippedForRightToLeftLayoutDirection()

此代码检查选定的方向并告诉ImageView以逆转图片。

在Apple的文档中,您可以找到一个代码,该代码通过NSAFFINETRANSFORM反映了图片本身。但是我们决定不使用此选项。

并非每张图片都可以自动镜像。例如,我们有带有渡渡鸟徽标的图片(橙色字母D和一只装有其中的鸟)。如果镜像,徽标将被颠倒,这是错误的。

无法自动镜像,必须重新绘制并放入项目中的图片。对于此资产,您可以设置本地化:

Image description

菜单中照片上的徽章

Image description Image description

照片上的徽章应移至另一个角落。在RTL中,它们应位于照片的左上角。

现在徽章是照片的一部分。我们计划使它们在应用程序中绘制。然后,当启用RTL时,我们将能够更改其位置。同时,这是不逆转照片的另一个原因。

动画

也必须对所有动画进行双重研究。我们很少有,但是我们在RTL中的功能不正确。

添加到购物车动画

启用RTL时会改变方向的一件事是Uitabbar。第一个标签将位于右侧,最后一个标签位于左侧。

让我们看一下添加到购物车动画的工作原理。该项目总是转到标签栏的最右边选项卡。虽然应该去购物车。

订单状态动画

加载动画应以另一种方式进行。

第三者

Image description Image description

不要忘记检查第三方服务。这就是我们的情况。

ivideon的广播上有一个文字。此文本是对齐的,并且文本本身可以在广播设置中更改。因此,没有问题。

但是,聊天和验证码根本不适合RTL。我们将无法自己解决,这意味着我们将不得不与SDK开发人员讨论潜在的改进。

WebView

Image description

我们在项目中有网络浏览量。他们打开了我们网站,Google文档,社交网络等的链接

您不需要对WebViews做任何事情,但是您需要记住将链接附加到本地化页面。

试图理解什么是错误,什么是功能

当我们第一次在应用程序中启用RTL时,我们的大脑都会破裂。

感知到非常困难和不寻常。一切看起来很奇怪,您不明白它是否看起来很糟糕,因为它是不寻常的,或者因为它被打破了。

看起来还不错,并且您不明白您是否习惯了RTL,或者看起来还不错,因为该元素以错误的方式显示,并且从左到右对齐。

有几个地方我们第一次紧张,但是事实证明一切都很好。在本节中,我们将讨论这样的地方。

输入字段

第一个是输入字段。

我们将应用程序切换到RTL,然后开始单击输入字段以编写内容。文字出现在杰里特的错误一侧,而杰特本身也没有移动。我们不得不修复它感到不高兴。

事实证明,如果输入字段处于RTL模式,并且您开始键入英文字母,则它们会出现在Caret的左侧,而Caret本身则保持到位。

但是,如果您开始键入阿拉伯语字母,则它们出现在Caret的左侧,而Caret本身向左移动。

应该的方式。

促销代码输入字段

Image description

我们的促销代码仅包含英文字母。英文字母从左到右拼写。这意味着必须将输入字段对齐左侧。

复数(.stringsdict)

Image description

最重要的是,所有复数字符串都在我们的应用中损坏。

在本文开头,我们讲述了该项目中两种伪语言。事实证明,逆转字母的人正在打破复数字符串。

该错误仅在调试期间发生。在使用阿拉伯线生产中,一切都很好。

我们很高兴并没有全部打破

我们不需要修改任何内容:

  • uinavigationbar(例如,在Android中,导航栏中的所有背部箭头都被打破了);
  • uitabbar;
  • uistackView;
  • uipageViewController;
  • 滑动以在表中删除;
  • 桌子中的分离器(在我们的情况下,一些分离器仅在屏幕边框的一侧都有一个插图。这是该插图应镜像。在Android上,它不起作用);
  • 输入字段(Unitextfield,UnitectVide);
  • uinavigation controller的动画(push/pop)和滑动以返回。

切换到RTL语言时会自动逆转所有上述元素:更改以选项卡,堆栈元素的顺序显示,UinaviationController动画的方向等。

让我们发现这些不需要任何修改,这是一个很好的惊喜:

  • 星星评估顺序;
  • SDK的故事。

处理晦涩的事物

在将应用程序定位为阿拉伯语时,还不足以适应UI,以便对RTL语言正确显示。考虑语言和文化的其他一些特征也很重要。

东阿拉伯数字

在阿拉伯语中,东部阿拉伯数字用于表示数字。它们与我们用过的不同之处:

Image description

应用程序中有很多地方使用数字:价格,克,电话号码等。几乎在您使用东阿拉伯数字所需的所有地方,但是有例外。例如,在价格标签和电话号码中,您需要使用东部阿拉伯数字,但对于银行卡号码,仅使用西方数字。

您可以在格式化器的帮助下转换数字:

extension String {

    var toLatnDigits: String? {
        let numberFormatter: NumberFormatter = NumberFormatter()
        numberFormatter.locale = Locale(identifier: "en_US")
        guard let latnNumber = numberFormatter.number(from: self) else { return nil }
        return numberFormatter.string(from: latnNumber)
    }
}

数字本身总是从左到右写的,包括电话号码。

顺便说一句,在某些情况下,iOS主动将西方数字转换为东阿拉伯语。例如,如果此字符串是阿拉伯语:

"resendCodeInDSecWithParam" = "Resend code in %d sec";

然后,在格式的字符串中,您将获得以东方阿拉伯数字编写的秒数:

let string = String.localizedStringWithFormat(
    NSLocalizedString(
        "resendCodeInDSecWithParam",
        bundle: bundle,
        comment: "Signup screen"
    ),
    Int(self.seconds)
)

记住检查需要数字输入的输入字段。例如,在我们的情况下,在结帐处的现场更改中,您可以输入以外的任何东西。

Image description

在应用程序中开始使用东部阿拉伯数字是一个大问题,不仅涉及应用程序,还涉及后端。我们决定在该应用程序的第一个版本中不支持阿拉伯语言支持的东部阿拉伯数字。为了解决应用程序中西部数字的使用,我们使用特殊的语言环境格式:带西方数字的阿拉伯语(ar-u-nu-latn)。

在哪一侧写什么

不要忘记检查什么位置:测量单位是在数字的左侧写入(尊指),而货币符号则写在右边(尊指$)。

如果指定时间间隔,则最终时间在左侧写,右边的开始时间。例如,如果比萨店从10:00到18:00开放,则写入如下:18:00-10:00。

用另一种语言的单词

如果阿拉伯文本中有外来单词,则不需要向后写。无需扭转俄语和英语的名称。例如,PayPal,Apple Pay。

标点

在阿拉伯语中,一些标点符号和其他符号不同。例如,他们使用不同百分比的符号。在我们的应用程序中,我们有一个带有百分比的图片,我们在屏幕上使用折扣和促销活动。当图片不能仅仅镜像时,情况正是这种情况,需要用另一个符号替换。

欧洲标志%是可以理解的,但是使用阿拉伯语是可取的。

百分比的定位可以通过字符串定位或使用格式化器来完成:

不喜欢这样:

label.text = String(localized: "(percentComplete)% complete")

但是这样:

label.text = String(localized: "(percentComplete.formatted(.percent)) complete")

此外,使用阿拉伯语表示数字(和#)的标志并不习惯。例如,我们使用此类标志显示应用程序中的订单数量。

熟悉的迹象被逆转:Øøâ®。

如何适应图片

Image description

以您期望的方式制作人的照片,即吸引注意力或引起热情的感觉,用户应将自己与这些图片中的角色联系起来。

如果您想实现此效果,请考虑使用中东观众而不是欧洲人的图像。例如,您最好避免在冬衣和耳朵张帽子中使用角色。

我们习惯了本地化意味着将应用程序适应特定语言的想法。最近,我们添加了在Dodo Pizza应用程序中手动更改语言的选项。当我们讨论阿联酋的图像时,我们得出的结论是,我们需要能够根据所选国家而不是选定的语言显示不同的插图。这就是我们为阿联酋所做的。

Image description

在其他国家也可以重复使用根据当前国家插入所需图像的代码。例如,它可以插入与之相关的冬季图像:

Image description

决定如何测试

有很多更改,所有更改都是接口。我们将通过快照测试测试RTL方向。对于快照测试,我们使用快照库。在那里您可以通过特征设置所需的方向来拍摄快照:

let rtlTrait = UITraitCollection(layoutDirection: .rightToLeft)
assertSnapshot(
    matching: sut,
    as: .image(traits: rtlTrait),
    testName: QuickSpec.current.name
 )

为方便起见,我们已经写了一个助手,以检查LTR和RTL的几个快照:

itShouldSnapshot(
    configs: [.default, .rightToLeft],
    matching: sut,
    configuration: { sut in
        let product = OrderHistoryViewModel.OrderProduct(
            name: "BBQ Wings",
            size: "8 pcs",
            imagePlaceholder: .imgPizzaGift,
            category: .pizza
        )

        var viewModel = OrderHistoryViewModel.PastOrderItem()
        viewModel.name = "BBQ Wings"
        viewModel.totalPriceString = "AED 26"
        viewModel.products = [product]

        sut.configure(viewModel: viewModel)
    },
    perceptualPrecision: precision,
    size: { sut in
        sut.sizeFitting(width: 320)
    }
)

稍后,我们将其升级以检查动态类型和暗模式。

得出结论

iOS使RTL语言的应用程序本地化的过程变得更加容易。我们可以说,我们需要在应用程序中适应的只是拍摄的技术债务。

结论:

  • 如果您从一开始就正确地进行布局,其余的将由iOS为您完成。
  • 您拥有的自定义元素越少,在RTL中看起来越好。
  • 工作并不以布局和翻译结束。也有很多文化特点,也很重要。
  • 文本的方向是所选语言的一个特征,但是有些事物不取决于语言,而是在国家。例如,应用程序中的插图
  • 并非所有图片都可以自动镜像。必须重新绘制一些东西。
  • 我们非常习惯LTR,因此最好向一些阿拉伯语的母语人士展示最终改编的应用程序,以免错过任何东西。
  • 快照测试加快了开发的速度,并帮助您确保沿途没有破坏任何东西。
  • RTL支持不是一次性事件,而是一个连续的过程。每个新功能都必须支持RTL。因此,您必须告诉团队设计时需要注意什么,为开发人员进行测试和说明清单。
  • 阿联酋是一个跨国国家。您只能以阿拉伯语为单位,也需要支持该应用程序。

要发现有关Dodo IS和Dodo品牌的顶级QSR创新的更多信息,请在LinkedInMedium上关注我们!