Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String interpolation in SwiftUI Text doesn't work with system locale correctly #169

Open
yo1995 opened this issue Apr 12, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@yo1995
Copy link
Collaborator

yo1995 commented Apr 12, 2023

Text("Z-value: \(model.zValue.formatted(.measurement(width: .narrow).locale(Locale(identifier: "en-CA"))))")

Shows as "Z-value: 70m"

Text("Z-value: \(model.zValue, format: .measurement(width: .narrow).locale(Locale(identifier: "en-CA")))")

Shows as "Z-value: 230'"

@philium
Copy link
Contributor

philium commented Apr 12, 2023

I suspect it is because SwiftUI views get the locale from the environment. Does this show the expected value?

Text("Z-value: \(model.zValue, format: .measurement(width: .narrow))")
    .environment(\.locale, Locale(identifier: "en-CA"))

@yo1995
Copy link
Collaborator Author

yo1995 commented Apr 13, 2023

Does this show the expected value?

Yes it shows the correct unit as "Z-value: 70m". It kind of makes sense that the priority is measurement string formatting locale > environment locale > measurement value string interpolation format style locale, but still hard to remember.

Simulator Screenshot - iPhone 14 Pro Max - 2023-04-13 at 10 51 05

I set the locale in Simulator as this - locale ID is still "en-US" while the measurement system is changed to Metric.
Using the older formatter API, the dimensions are correctly displayed as metric units, while the SwiftUI formatting style, or formatted() are displayed as imperial.

I'll keep digging to see if SwiftUI formatting style APIs support displaying a different measurement system than the locale's default.

@yo1995 yo1995 added the enhancement New feature or request label Apr 13, 2023
@philium
Copy link
Contributor

philium commented Apr 13, 2023

I'll keep digging to see if SwiftUI formatting style APIs support displaying a different measurement system than the locale's default.

MeasurementFormatUnitUsage.asProvided might be what you're looking for.

@philium
Copy link
Contributor

philium commented Apr 13, 2023

On iOS 16 and newer there is Locale.measurementSystem, which sounds like what you want. It can be specified by creating a locale using Locale.init(components:):

var components = Locale.Components(locale: .current)
components.measurementSystem = .metric
let locale = Locale(components: components)

@yo1995
Copy link
Collaborator Author

yo1995 commented Apr 13, 2023

Thanks Phil. This definitely looks like the correct way to go. Though I tested in iOS 16, it doesn't behave as expected. I'll add this issue to iOS 16 and beyond column and take a look in the future.

@yo1995 yo1995 added this to iOS 16 and Beyond in SwiftUI Sample Viewer prototyping Apr 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Development

No branches or pull requests

2 participants