Buttons in menu don't respect the environment value of .layoutDirection in SwiftUI

Problem

Setting ".environment(.layoutDirection, .rightToLeft)" to a view programmatically won't make buttons in menu to show right to left.

However, setting ".environment(.locale, .init(identifier: "he-IL"))" to a view programmatically makes buttons in menu to show Hebrew strings correctly.

Development environment: Xcode 16.x, macOS 15.3.1

Target iOS: iOS 17 - iOS 18

The expected result is that the button in the menu should be displayed as an icon then a text from left to right.

Code to demonstrate the problem:

struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Buttons in menu don't respect the environment value of .layoutDirection")
.font(.subheadline)
.padding(.bottom, 48)
/// This button respects both "he-IL" of ".locale" and ".rightToLeft" of ".layoutDirection".
Button {
print("Button tapped")
} label: {
HStack {
Text("Send")
Image(systemName: "paperplane")
}
}
Menu {
/// This button respects "he-IL" of ".locale" but doesn't respect ".rightToLeft" of ".layoutDirection".
Button {
print("Button tapped")
} label: {
HStack {
Text("Send")
Image(systemName: "paperplane")
}
}
} label: {
Text("Menu")
}
}
.padding()
.environment(\.locale, .init(identifier: "he-IL"))
.environment(\.layoutDirection, .rightToLeft)
}
}

@shengxu01 Thanks for flagging this. It looks like a bug to me. I'd greatly appreciate it if you could open a bug report, include the code snippet that reproduces the issue and post the FB number here once you do. Bug Reporting: How and Why? has tips on creating your bug report.

Thanks for the reply. The FB number for the bug is FB17011275. The link to the bug is https://feedbackassistant.apple.com/feedback/17011275.

As my colleague said, that changing the UI language using SwiftUI environment (\.locale) works for the button but not for the menu is most likely a SwiftUI bug, and thanks for filing the bug report.

Maybe worth mentioning though, changing the system or per-app language setting is the standard way of changing an app's language – If you do so on your device, you will see that the button and the menu both work correctly.

I am wondering why you would change the UI language using .locale. If your intent is to provide an in-app language switcher that allows users to change the language without leaving your app, you might want to evaluate it carefully, because changing SwiftUI locale environment only impacts the SwiftUI view hierarchy, and not the system-provided components.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Buttons in menu don't respect the environment value of .layoutDirection in SwiftUI
 
 
Q