使用 MeasurementFormatter 选择单位

Choosing units with MeasurementFormatter

这与 类似,但我得到的答案在这种情况下似乎不起作用。

我正在从核心位置获取以米为单位的高度值。我想以本地化形式显示这些。例如,我现在所在的海拔高度为 1839 米。这应该显示为 6033 英尺。我能用 MeasurementFormatter 做的最好的事情是“1.143 英里”。

let meters : Double = 1839
let metersMeasurement = Measurement(value: meters, unit: UnitLength.meters)

let measurementFormatter = MeasurementFormatter()
measurementFormatter.locale = Locale(identifier: "en_US")

let localizedString = measurementFormatter.string(from: metersMeasurement)

回答我上一个问题的 .naturalScale 选项在这里没有帮助。我认为这是框架的限制,但我想知道现在是否有人有解决方法。

我认为你是对的,没有办法指定这种上下文。你可以这样做:

extension MeasurementFormatter
{
    func altitudeString(from measurement: Measurement<UnitLength>) -> String
    {
        var measurement = measurement
        let unitOptions = self.unitOptions
        let unitStyle = self.unitStyle
        self.unitOptions = .naturalScale
        self.unitStyle = .long
        var string = self.string(from: measurement)
        if string.contains(self.string(from: UnitLength.miles))
        {
            self.unitStyle = unitStyle
            measurement.convert(to: UnitLength.feet)
            self.unitOptions = .providedUnit
            string = self.string(from: measurement)
        }
        else if string.contains(self.string(from: UnitLength.kilometers))
        {
            self.unitStyle = unitStyle
            measurement.convert(to: UnitLength.meters)
            self.unitOptions = .providedUnit
            string = self.string(from: measurement)
        }
        else
        {
            self.unitStyle = unitStyle
            string = self.string(from: measurement)
        }
        self.unitOptions = unitOptions
        return string
    }
}

也许还有其他特定于文化的测量海拔的方法,但这似乎比英里和公里更好。

您只需将 UnitLength 从米转换为英尺。您还可以创建自定义美国测量格式化程序以根据需要显示它:

extension Measurement where UnitType == UnitLength {
    private static let usFormatted: MeasurementFormatter = {
       let formatter = MeasurementFormatter()
        formatter.locale = Locale(identifier: "en_US")
        formatter.unitOptions = .providedUnit
        formatter.numberFormatter.maximumFractionDigits = 0
        formatter.unitStyle = .long
        return formatter
    }()
    var usFormatted: String { Measurement.usFormatted.string(from: self) }
}

游乐场

let value: Double = 1839
let meters: Measurement<UnitLength> = .init(value: value, unit: .meters)
let feet = meters.converted(to: .feet)
let formatted = feet.usFormatted
print(formatted)    // "6,033 feet"\n