read

In the new string catalog, you can easily right click > Vary by Plural > Edit it as you like.

But that’s not the only way. In WWDC 2021, you can use markdown to apply style.

    Text("**Bold world**")
    Text("_Italy world_")
    Text("~~Cancer~~ world")
    Text("`Text(isGood)`")
    Text("Link to [website](https://samwize.com)")
        .tint(.pink)

That’s not all. You can add custom attributes to AttributedString. For SwiftUI, a custom attribute syntax is

    Text("^[Text with foo & bar attributes](foo: xxx, bar: 123)")

That annotates the text with foo=xxx and bar=123.

You can apply style using such special attributes.

Plural in Text

That brings us to the topic of how to pluralize. You can apply the inflect=true attribute to part of the string:

    Text("^[\(0) friend](inflect: true)") // 0 friends
    Text("^[\(1) friend](inflect: true)") // 1 friend
    Text("^[\(2) friend](inflect: true)") // 2 friends

To be clear, there must be an integer argument for the inflect to happen.

That is obvious, but what if the integer is not part of the text? Read on for a solution.

No integer in the string

I saw this from lickability, and will use their example of “New Message” or “New Messages” that is shown in a notification banner.

This is the extension he provided:

    extension Text {
        init(_ text: String, countToInflect: Int) {
            if countToInflect == 1 {
                self.init("^[\(text)](morphology: { number: \"one\" }, inflect: true)")
            } else {
                self.init("^[\(text)](morphology: { number: \"other\" }, inflect: true)")
            }
        }
    }

The morphology attribute can accept a JSON that specify the “number” for pluralization. But for simple pluralization, we can just use the convenient init.

    Text("New Message", countToInflect: 0) // New Messages
    Text("New Message", countToInflect: 1) // New Message
    Text("New Message", countToInflect: 2) // New Messages

Image

@samwize

¯\_(ツ)_/¯

Back to Home