大师学SwiftUI第20章 - 国际化

简介: 苹果的产品遍布一百多个国家,使用几十种语言和方言发行应用,但通常我们只能创建一个版本的应用,所以就需要对不同市场进行适配。这不仅仅是翻译,还有用户界面中元素的排列、数字的格式等等。这一客制化的过程称为本地化。在SwiftUI中,大多数本地化会自动完成。例如,SwiftUI视图的内容采用靠前(leading)和靠后(trailing)约束来根据文字顺序(从左到右或从右到左读)的不同来表示左和右,日期和充其量单位等值会自动根据所在地进行格式化(参见示例4-32)。但文本还是需要我们来翻译。为此Xcode提供了字符串名录(String Catalogs)。

苹果的产品遍布一百多个国家,使用几十种语言和方言发行应用,但通常我们只能创建一个版本的应用,所以就需要对不同市场进行适配。这不仅仅是翻译,还有用户界面中元素的排列、数字的格式等等。这一客制化的过程称为本地化。在SwiftUI中,大多数本地化会自动完成。例如,SwiftUI视图的内容采用靠前(leading)和靠后(trailing)约束来根据文字顺序(从左到右或从右到左读)的不同来表示左和右,日期和充其量单位等值会自动根据所在地进行格式化(参见示例4-32)。但文本还是需要我们来翻译。为此Xcode提供了字符串名录(String Catalogs)。

String Catalogs

字符串名录是由Xcode所提供了一个工具,借助它我们可以进行文本翻译、适配目标语言。系统会跟踪代码中的本地化文本,创建一个文件供我们编辑和发送给专业的翻译人员。该文件的创建方式和其它文件一样通过File菜单,选项们于Resource版块下。

图20-1:字符串名录文件

文件可使用任意名称,添加后的效果如下:

图20-2:在项目中添加字符串名录

每次运行或构建程序时,系统会跟踪视图、更新该文件的内容。我们使用一个简单的视图来进行测试。

例20-1:测试字符串名录:

import SwiftUI
struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello World!")
                .padding()
            Spacer()
        }
    }
}

这一视图包含一个Text视图,文本为"Hello World!"。在运行或构建应用时(Command + B),这段文字会进入字符串名录文件中,如下图所示。

图20-3:更新后的字符串名录文件

选中字符串名录文件时,Xcode会显示一个可编辑其内容的界面。该界面左侧面板显示可用语言,右侧提供了各种语言的翻译和适配信息。

当前创建的文件仅使用了默认语言(本例中为英语)。点击左下角的+按钮添加一种语言。点击该按钮时,会弹出一个可添加的语言列表。

图20-4:语言

添加好语言后,可以点击对应的语言为各段文本添加翻译。下例中我们添加了西班牙语及其翻译文本。

图20-5:西班牙语翻译

✍️跟我一起做:创建一个多平台项目。按照例20-1中的代码更新ContentView视图。打开File菜单,创建一个字符串名录文件(图20-1)。在模拟器中运行应用或按下Command + B构建应用。打开字符串名录文件。应该会在列表中看到"Hello World!"文本。使用该项目测试本章后续的示例。

本地化已就绪。此时在说西语的国家打开应用,Text视图中显示的文本就是"Hola Mundo!"。这在用户的设备上自动完成,但若要在Xcode上测试就需要修改schema或配置预览。通过更改schema,可以在模拟器或设备上测试本地化。点击Xcode工具栏中的项目名称,选择Edit Scheme...选项即可编辑schema,如下图所示。

图20-6:Schema菜单

这会打开一个包含所有项目配置选项的窗口。修改语言必须点击Run打开Options面板,通过App Language选项选取语言(图20-7,1号标注)。

图20-7:应用语言选项

代码请见:GitHub仓库

在配置成希望显示的语言后,预览、模拟器和设备都会使用这一配置运行应用。如果只希望在预览界面测试本地化,可以仅实现如下的环境属性。

  • layoutDirection:本属性决定文本的书写朝向。它是一个LayoutDirection枚举,值有leftToRight和rightToLeft。
  • locale:本属性决定视图所使用的位置。它是一个Locales结构体。

要修改这些属性,必须对预览应用enviroment()修饰符,和第5章中的操作一样(例5-93)。例如,我们可以创建两个预览,一个使用默认语言,另一个使用西班牙语。

示例20-2:选取预览的语言

#Preview {
    ContentView()
}
#Preview {
    ContentView()
        .environment(\.locale, Locale(identifier: "es"))
}

此时预览界面中会显示两个预览,一个使用英语文本("Hello World!"),另一个使用西语文本("Hola Mundo!")。

图20-8:多语言预览

Xcode所提供的编辑字符串名录的界面仅适用开发者。如果与第三方翻译人员合作,可以导出文件,在拿回翻译文件后再进行导入。这一选项位于Product菜单中(图20-9,一号标注)。

图20-9:导出/导入选项

在将本地化文件发送给翻译人员时,推荐包含注释协助他们实现最精准的翻译。为此,Text视图包含了如下的初始化函数:

  • Text(String, comment: StaticString?):这一初始化函数创建一个Text视图,通过第一个参数指定其文本,通过comment参数指定注释。StatictString结构体是设计用于表示在应用编译后不再发生变化的文本。

我们可以使用这个初始化函数在界面中创建所有的Text视图。下例中,我们对Text视图添加注释,以便翻译知道这段文本的作用。

示例20-3:添加供翻译查看的注释

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello World!", comment: "This is a welcome message")
                .padding()
            Spacer()
        }
    }
}

系统跟踪视图查找可包含在字符串名录中的本地化文本。如果文本存储在属性中,或是由外部进程生成,就必须将其声明为可本地化,否则系统找不到。为此String结构体包含有如下的初始化函数。

  • String(localized: String):此初始化函数创建一个带本地化字符串的String结构体。

通过这个初始化函数,我们可以本地化所有需要对用户显示的文本。例如,我们可以在视图中添加一个按钮,在点击后修改某个Text视图中的文本,然后同时本地化原始文本和按钮所赋值的文本。

注意当前在预览窗口中仅有按钮的文本会本地化。

示例20-4:本杝化字符串

struct ContentView: View {
    @State private var mytext = String(localized: "Hello World!")
    var body: some View {
        VStack {
            Text(mytext)
                .padding()
            Button("Change Text") {
                mytext = String(localized: "Goodbye World!")
            }
            Spacer()
        }
    }
}

在应用构建时,系统会跟踪社图,查找Button视图中的文本,然后检查代码找到更多的本地化文本。本例中我们声明了两个本地化String结构体,一个设置Text视图的初始文本,另一个赋值给点击按钮后的社图。此时字符串名录包含三段翻译文本。

图20-10:待翻译的本地化文本

如果通过某个进程接收到常规字符串,我们可以通过定义类型为LocalizedStringResource的属性来告知系统该字符串是可本地化的。这个结构体包含指定该文本的初始化函数,还有一个可选注释参数。

  • LocalizedStringResource(String, comment: StaticString?):这一初始化函数创建一个结构体,表示从其它程序接收到的可本地化字符串。

例如我们在希望接收到的常规化字符串可进行本地化时使用这一结构体。

示例20-5:值的本地化

struct ContentView: View {
    var body: some View {
        VStack {
            MyView(mytext: "Hello World!")
            Spacer()
        }
    }
}
struct MyView: View {
    let mytext: LocalizedStringResource
    var body: some View {
        Text(mytext)
            .padding()
    }
}

除了翻译外,字符串名录还可用于指定文本的单复数。如果文本中包含该值,系统会自动选择正确的文本显示给用户。例如,下例中包含一个存储整数的@State属性,以及一个在屏幕上进行显示的Text视图。每次点击按钮时,值会递增1。

示例20-6:指定文本的单数和复数版本

struct ContentView: View {
    @State private var counter = 1
    var body: some View {
        VStack {
            Text("\(counter) Item")
                .padding()
            Button("Add Unit") {
                counter += 1
            }
            Spacer()
        }
    }
}

在Text视图中,和counter属性值一同显示的还有单词"Item"。问题是在值在于1时文本应显示为"Items"。我们可以打开字符串名录为该文本设置两个版本,按住Control键点击该单词。此时会打开一个菜单,包含指定设备设置不同版本以及设置单复数的选项。

图20-11:版本菜单

选择Vary by Plural选项,系统会为单复数创建两个新字段。

图20-12:单数和复数版本

本例中,单数指定为"Item",复数版本指定为"Items"。

此时会根据counter属性的值向用户展示不同版本的文本。

图20-13:按属性值展示文本

其它相关内容请见虚拟现实(VR)/增强现实(AR)&visionOS开发学习笔记

相关文章
|
1月前
|
iOS开发 开发者 UED
探索iOS应用开发中的SwiftUI框架
【9月更文挑战第26天】 在iOS开发的海洋中,SwiftUI犹如一艘现代的快艇,引领着开发者们驶向更加高效与直观的编程体验。本文将带你领略SwiftUI的魅力,从其设计理念到实际应用,我们将一步步揭开它如何简化界面构建过程的面纱。通过对比传统方式,你将看到SwiftUI如何让代码变得像诗一样优美,同时保持强大的功能性和灵活性。准备好让你的iOS开发技能加速升级,一起驾驭这股新潮流吧!
|
2月前
|
设计模式 Java Android开发
探索安卓应用开发:从新手到专家的旅程探索iOS开发中的SwiftUI框架
【8月更文挑战第29天】本文旨在通过一个易于理解的旅程比喻,带领读者深入探讨安卓应用开发的各个方面。我们将从基础概念入手,逐步过渡到高级技术,最后讨论如何维护和推广你的应用。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的代码示例。让我们一起开始这段激动人心的旅程吧!
|
2月前
|
Rust 前端开发 JavaScript
震惊!JavaScript 与 WebAssembly 强强联合,开启前端性能传奇之旅,你准备好了吗?
【8月更文挑战第27天】在互联网飞速发展的今天,前端技术,特别是核心语言JavaScript,正经历着持续的革新。为了突破JavaScript在处理复杂计算时的性能局限,WebAssembly应运而生。作为一种高效的二进制格式,WebAssembly能以接近原生的速度在浏览器中运行,支持C、C++和Rust等语言编写的高性能代码。它与JavaScript相辅相成,前者专注于高性能计算任务(如游戏开发、图像处理),后者则负责页面的交互与逻辑控制。通过结合使用,二者为前端开发者提供了更为强大和灵活的工具集,共同推动前端技术进入一个全新的性能时代。
63 2
|
2月前
|
存储 前端开发 JavaScript
Rails 的国际化支持太厉害了!全球用户轻松搞定,快来看看这逆天的编程神技!
【8月更文挑战第31天】《Rails中的国际化(i18n)支持》深入探讨了Ruby on Rails框架的国际化特性。文章从翻译文件组织、翻译提取管理、动态翻译、地区语言切换及前后端国际化支持五个方面详细介绍了Rails的优势,并与其他框架进行了对比,展示了其在开发全球化应用时的强大功能与便捷性。
27 0
|
2月前
|
Java 数据库连接 Spring
Struts 2 插件开发竟如魔法盛宴,为框架注入超能力,开启奇幻编程之旅!
【8月更文挑战第31天】在Web开发中,Struts 2插件开发允许我们在不改动框架核心代码的前提下,通过创建实现特定接口的Java类来扩展框架功能、调整其行为或促进与其他框架(如Spring、Hibernate)的集成,从而更好地满足特定业务需求。遵循良好的设计原则与实践,能够确保插件的高效稳定运行并提升整体项目的可维护性。具体步骤包括创建项目、定义插件类、实现初始化与销毁逻辑,并将插件部署至应用中。
52 0
|
3月前
|
Swift iOS开发 开发者
iOS应用开发:SwiftUI高级技巧
【7月更文挑战第21天】SwiftUI以其声明式语法、跨平台一致性、强大的动画和状态管理特性,为iOS应用开发带来了革命性的变化。通过掌握SwiftUI的高级技巧,开发者可以构建出更加高效、美观和流畅的应用。希望本文能够帮助你更好地理解和应用SwiftUI,从而在iOS应用开发的道路上走得更远。
|
2月前
|
开发工具 Swift iOS开发
探索iOS开发:SwiftUI的革新之旅
在这篇文章中,我们将一起踏上SwiftUI的探索之旅,这是苹果公司为简化iOS应用开发而推出的现代框架。不同于传统的摘要形式,本文将通过一系列引人入胜的故事和实例,带领读者深入理解SwiftUI如何改变开发者构建应用程序的方式。从基础概念到高级技巧,每个环节都像拼图一样紧密相连,共同描绘出一幅关于创新、效率和用户体验提升的宏伟画卷。
|
3月前
|
机器学习/深度学习 人工智能 iOS开发
探索iOS开发的未来:SwiftUI的革新之旅
在数字时代的浪潮中,iOS开发正经历一场由SwiftUI引领的变革。本文将深入探讨SwiftUI如何重塑移动应用开发,提升开发者的生产力,并展望其对iOS生态的影响。通过分析SwiftUI的核心特性、实际案例和未来趋势,我们将揭示这一现代框架如何定义用户体验的新标准,同时为iOS开发者指明技术进阶之路。
|
3月前
|
API Swift iOS开发
探索iOS开发:SwiftUI框架的革新之旅
【7月更文挑战第2天】在这篇文章中,我们将深入探讨SwiftUI——苹果为简化iOS界面开发而设计的现代框架。不同于传统的摘要概述,我们将通过一个开发者的视角,逐步揭示SwiftUI如何改变iOS应用的构建过程,并分享一些实用的技巧和最佳实践,以助你快速上手这一前沿技术。
|
11月前
|
存储 vr&ar Swift
大师学SwiftUI第16章 - UIKit框架集成
SwiftUI是一套新框架,因此并没有包含我们构建专业应用所需的所有工具。这意味着我们会需要求助于UIKit(移动设备)和AppKit(Mac电脑)等原生框架所提供的工具。
82 0