Home > Net >  How can i provide two different fonts to a text based on the current Locale in SwiftUI?
How can i provide two different fonts to a text based on the current Locale in SwiftUI?

Time:01-09

I'm trying to create an app that will support two languages, the first one is English and the second one is the Kurdish language which uses letters that are similar to Arabic letters (ا،ب،ج). I want to give a text a specific font based on the selected locale of the app, for example, if the selected language is English I want the app to have the default font supplied by apple and if the locale is Kurdish I will supply my custom font. I know how to load a custom font and assign it individually to a specific text but I want to create some sort of a modifier that will handle the locality logic and apply the appropriate font based on the locale instead of checking for the locale in every text I create. here is a snippet code of what I'm trying to achieve:

Text("Test")
   .font(Font.myTitle())

Text will be "test" in English and will be "تێست" Kurdish.

I tried to extend the font to read from the environment variable but I guess I was wrong since environment variables are available only in views. here is what I tried in the extension:

extension Font{
    public static func myTitle() -> Font{
        @Environment(\.locale) var locale: Locale
        let isKurdish = locale.identifier == "ku"
        if(isKurdish) {
            return Font.custom("rabar_013", size: 30)
        }
        return Font.title
    }
}

Can anyone provide a solution to this problem?

CodePudding user response:

Instead of using an extension on Font you can create your own ViewModifier that will have access to the Environment.

Something like this should do it.

struct LanguageTitleModifier: ViewModifier {
    @Environment(\.locale) private var locale

    func body(content: Content) -> some View {
        content
            .font(font)
    }

    private var font: Font {
        let isKurdish = locale.identifier == "ku"
        if isKurdish {
            return Font.custom("rabar_013", size: 30)
        } else {
            return Font.title
        }
    }
}

You can then create a helper extension on View so that it is easier to use.

extension View {
    func languageTitle() -> some View {
        self.modifier(LanguageTitleModifier())
    }
}

You then use it in the following way:

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .languageTitle()
    }
}

CodePudding user response:

There are 2 options with your current code

extension Font{
    public static func myTitle() -> Font{
        let locale = Locale.autoupdatingCurrent //Takes the device Locale
        let isKurdish = locale.identifier == "ku"
        if(isKurdish) {
            return Font.custom("rabar_013", size: 30)
        }
        return Font.title
    }
    public static func myTitle(locale: Locale) -> Font{
        let isKurdish = locale.identifier == "ku"
        if(isKurdish) {
            return Font.custom("rabar_013", size: 30)
        }
        return Font.title
    }
}

For the second one you can use in your View

@Environment(\.locale) private var locale

and then pass it to use the environment's locale instead of the device's

Text("Test")
   .font(Font.myTitle(locale: locale))
  • Related