3

iOS 15 中新增了英语和西班牙语的语法协议功能。例如,我应该可以说

You have x apple.

如果x是 1,那么“apple”就是“apple”,但如果x大于 1,那么“apple”就会神奇地变成“apples”。

这听起来像是摆脱所有代码的好方法,我自己正在查看数字并在硬编码的单数和复数选项之间进行选择。

但是,在我看来,此功能仅适用于本地化应用程序,并且仅适用于 UIKit 中的属性字符串。(SwiftUI 是不同的,因为字符串是自动本地化的。)我如何为普通的面向用户的字符串执行此操作?

4

1 回答 1

7

您必须使用本地化的属性字符串才能获得此功能。但这并不意味着您提供的字符串必须本地化或归因!

这是一个例子。在某些时候,我们可能会这样说:

let count = 1
let output = String(AttributedString(
    localized:"You have ^[\(count) \("apple")](inflect: true).").characters)
print(output) // You have 1 apple.

现在想象一下,在其他时候,我们这样说:

let count = 2
let output = String(AttributedString(
    localized:"You have ^[\(count) \("apple")](inflect: true).").characters)
print(output) // You have 2 apples.

请注意,我的属性字符串在两者中是相同的。然而,基于该count值,运行时已在需要时将“apple”更改为“apples”。这正是我们想要的。

所以这是交易,据我所知。

  • 您必须使用属性字符串,并且必须将其声明为本地化(在 UIKit 中)。

  • 一旦你这样做了,你就可以使用 Markdown。您确实使用 Markdown,使用 Apple 设计的特殊自定义属性语法。这样,字符串的变形区域对运行时可见。

  • 所有相关的内容都必须包含在方括号部分中,并且必须使用字符串插值进行标记,正如我在这里展示的那样。在这种情况下,“一切相关”是计数和名词。名词用单数;如果你使用复数,它不会被屈折成单数,但如果你使用单数,它会被屈折成复数。

  • 字符串本身必须是文字才能获得特殊的插值规则;特别是,它必须输入为 StringLocalizationKey。我可以这样构造字符串:

    let count = 2
    let s : StringLocalizationKey = "You have ^[\(count) \("apple")](inflect: true)."
    

这给了你自动变形。然后,在这种情况下,因为我只想要字符串,所以我通过characters属性字符串的视图并将其强制转换为字符串。

请注意,我的应用程序没有任何有意义的本地化。我没有为应用程序声明其他语言,也没有.strings文件或.stringsDict文件。我只通过localized:构造函数,因为这就是您访问此功能的方式。

于 2021-06-28T01:21:47.797 回答