UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: How to localize Text() inside a List?

Forums > SwiftUI

Good evening, I have created a test project at Github showing my problem:

screenshot

It displays a list of games in the ContentView.swift:

List($vm.currentGames, id: \.self) { $gameNumber in
    NavigationLink(
            destination: GameView(gameNumber: gameNumber)
        ) {
        Text("game-number #\(gameNumber)")
    }
}

which is coming from the GamesViewModel.swift:

class GamesViewModel: ObservableObject /*, WebSocketDelegate */ {
    @Published var currentGames: [Int] = [20, 30]
    @Published var displayedGame: Int = 0

And for localization in DE, EN, RU I have added Localizable.strings:

"app-title" = "Wähle ein Spiel!";
"update-games" = "Spiele erneuern";
"join-random-game" = "Zufallsspiel beitreten";
"game-number #%d" = "Spiel #%d";

If you look at the above screenshot, you will see that the first 3 entries are localized properly, but the last one game-number #%d is not working (marked by the red arrow in the screenshot)

Is it because the Text is inside of a List and is updated dynamically?

Best regards Alex

3      

Trying usng the placeholder %lld instead of %d.

3      

Thanks for replying! Here the things I have already unsuccessfully tried:

  • Replaced %d by %lld
  • Removed the # char on both sides
  • Replaced game-number by just game
  • Tried to use Text(LocalizedStringKey("game-number #\(gameNumber)"))
  • Tried to use Text(String(format: NSLocalizedString("game-number #%d", comment: ""), gameNumber)) (always shows EN)

3      

The first three work because Text will automatically look for those keys in Localizable.strings. I've found it to be hit or miss with interpolated strings and struggled with an issue just like yours.

My solution was to write a func that would return the desired string. It didn't feel very SwiftUI-y to me, but it worked, and I needed to move on haha.

func gameNumberTitle(for int: Int) -> String {
  let numberString = String(int)
  let gameNumberTitle = String(format: NSLocalizedString("game-number %@" , comment: ""), numberString)
  return gameNumberTitle
}

In localizable.strings, you'd have:

"game-number %@" = "Spiel #%@";

And you'd use it in your View like:

List($vm.currentGames, id: \.self) { $gameNumber in
    NavigationLink(
            destination: GameView(gameNumber: gameNumber)
        ) {
        Text(gameNumberTitle(gameNumber))
    }
}

3      

When you run it in tthe dubug usally get

[strings] ERROR: /*the string*/ not found in table Localizable of bundle CFBundle

Then you should have what the complier looking for?

3      

Good evening, no I do not see any bundle related errors, when compiling or when debugging the app.

However, I have now got a good workaround advice at the Stackoverflow:

List($vm.currentGames, id: \.self) { $gameNumber in
    NavigationLink(
        destination: GameView(gameNumber: gameNumber)
    ) {
        Text("game-number #\(String(gameNumber))")
    }
}

And use the string instead of the number in the Localizable.strings:

"game-number #%@" = "Game #%@";
"game-number #%@" = "Spiel #%@";
"game-number #%@" = "Игра #%@";

Best regards Alex

3      

As an addition to what @matthewloewen mentioned about interpolated strings being "hit or miss", this is often because we really shouldn't be interpolating strings themselves, but rather Texts. This keeps everything as a LocalizedStringKey.

Text("game-number #\(Text(gameNumber, format: .number))")

This should result in the Localized.strings working correctly. Another benefit to this approach is when you use Export Localizations in Xcode that the compiler can also better identify your LocalizedStringKeys.

4      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.