Views not mirrored for RTL languages

131 Views Asked by At

I’m trying to localize my SwiftUI app for RTL languages but having trouble getting the views to be mirrored (navigation presentation direction, link chevron direction, toolbar items location etc.) I created a really simple project with the code below and when I edit the scheme to use “Right-to-Left Pseudolanguage” for “App Language” the views do get mirrored. However, when I choose Hebrew or Arabic or even set the simulator or device's system language to an RTL language, it doesn’t mirror and shows the same way it does for LTR languages.

struct ContentView: View {
  var body: some View {
    NavigationStack {
      List {
        ForEach(1..<10) { i in
          NavigationLink {
            Text("Hello world")
          } label: {
            Text("\(i)")
          }
        }
      }
    }
  }
}

The first image is what I expect (when using “Right-to-Left Pseudolanguage”) and second image is how it's shown for Hebrew/Arabic which isn't mirrored

enter image description here enter image description here

2

There are 2 best solutions below

1
workingdog support Ukraine On BEST ANSWER

Try this approach using a variable to modify the layoutDirection

Example code:

struct ContentView: View {
    @State private var isRTL = false  // <-- here
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(1..<10) { i in
                    NavigationLink {
                        Text("Hello world")
                    } label: {
                        Text("\(i)")
                    }
                }
            }
        }
        .onAppear {
            isRTL = Locale.current.language.languageCode?.identifier == "he"  // <-- here
        }
        .environment(\.layoutDirection, isRTL ? .rightToLeft : .leftToRight)  // <-- here
    }
    
}
0
Jayant Badlani On

you can try explicitly setting the layout direction for your views. Check LayoutDirection, A direction in which SwiftUI can lay out content.

you can update your code like this to achieve right to left layouts.

enter image description here

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(1..<10) { i in
                    NavigationLink {
                        Text("Hello world")
                    } label: {
                        Text("\(i)")
                    }
                }
            }
        }
        .environment(\.layoutDirection, isRTL() ? .rightToLeft : .leftToRight)
    }
    
    func isRTL() -> Bool {
        let languageCode = Locale.current.language.languageCode?.identifier
        return ["he", "ar"].contains(languageCode)
    }
}

#Preview {
    ContentView()
}

https://developer.apple.com/documentation/swiftui/layoutdirection