NSLengthFormatter 仅在 miles/kilometers 中获取 stringFromMeters:

NSLengthFormatter get stringFromMeters: in miles/kilometers only

我正在使用 NSLengthFormatter class 来格式化用户和某个目的地之间的距离。

CLLocation *userLocation; //<- Coordinates fetched from CLLocationManager
CLLocation *targetLocation; //<- Some location retrieved from server data

CLLocationDistance distance = [userLocation distanceFromLocation:targetLocation];

NSLengthFormatter *lengthFormatter = [NSLengthFormatter new];
NSString *formattedLength = [lengthFormatter stringFromMeters:distance];

现在,如果长度小于 1000 米,格式化的距离总是以码或米显示(取决于区域设置)。

例如。如果距离 = 450.0,格式化字符串将为 492.7 yd 或 450 m。

如何将 NSLengthFormatter 调整为 return 仅 miles/kilometers 中的距离字符串?

似乎没有办法选择退出此行为。老实说,从用户体验的角度来看,你的要求并不常见。

请注意,meter 是基本单位,而不是 kilometer(千米)。通常,显示 10 meters 优于显示 0.01 kilometers。它只是对用户更友好。

实际上很难设计一个 API 来执行特定的单位,因为基本单位取决于当前的语言环境。

您可以使用以下方法强制执行特定单位:

- (NSString *)unitStringFromValue:(double)value unit:(NSLengthFormatterUnit)unit;

但您必须自己处理语言环境、缩放比例和单位转换(参见 Objective c string formatter for distances

这是我最终使用的:

-(NSString *)formattedDistanceForMeters:(CLLocationDistance)distance
 {
    NSLengthFormatter *lengthFormatter = [NSLengthFormatter new];
    [lengthFormatter.numberFormatter setMaximumFractionDigits:1];

    if ([[[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem] boolValue])
    {
        return [lengthFormatter stringFromValue:distance / 1000 unit:NSLengthFormatterUnitKilometer];
    }
    else
    {
        return [lengthFormatter stringFromValue:distance / 1609.34 unit:NSLengthFormatterUnitMile];
    }
}

编辑:

Swift 中的相同内容如下所示:

func formattedDistanceForMeters(distance:CLLocationDistance) -> String {
        let lengthFormatter:NSLengthFormatter! = NSLengthFormatter()
        lengthFormatter.numberFormatter.maximumFractionDigits = 1

        if NSLocale.currentLocale().objectForKey(NSLocaleUsesMetricSystem).boolValue()
        {
            return lengthFormatter.stringFromValue(distance / 1000, unit:NSLengthFormatterUnitKilometer)
        }
        else
        {
            return lengthFormatter.stringFromValue(distance / 1609.34, unit:NSLengthFormatterUnitMile)
        }
    }

对于不使用公制的人来说,这实际上是一个非常普遍的要求(是的,我知道...)。

在公制系统中,从公里到米等等是有意义的。如果您遵循与英制系统相同的逻辑,您将从英里到码再到英尺。

通常您不想使用 Yards 表示道路距离,例如您不想显示 5,000 英尺而是 0.9 英里(实际上 Google 地图以英尺显示最多 0.1 英里或 528 英尺,然后以英里为单位)。

let distanceAsDouble = 415.0

let lengthFormatter = LengthFormatter()

if Locale.current.usesMetricSystem {
    return distanceFormatter.string(fromMeters: distanceAsDouble)
} else {
    let metersInOneMile = Measurement<UnitLength>(value: 1.0, unit: .miles).converted(to: .meters).value
    if distanceAsDouble < metersInOneMile / 10 { // Display feets from 0 to 0.1 mi, then miles
        let distanceInFeets = Measurement<UnitLength>(value: distanceAsDouble, unit: .meters).converted(to: .feet).value
        return distanceFormatter.string(fromValue: distanceInFeets, unit: .foot)
    } else {
        return distanceFormatter.string(fromValue: distanceAsDouble / metersInOneMile, unit: .mile)
    }
}
-(NSString *)formattedDistance {
     
    CLLocationDistance distance = _distance;
     
    NSLengthFormatter *lengthFormatter = [NSLengthFormatter new];
    [lengthFormatter.numberFormatter setMaximumFractionDigits:1];

    if ([[[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem] boolValue])
    {
        return [lengthFormatter stringFromValue:distance / 1000 unit:NSLengthFormatterUnitKilometer];
    }
    else
    {
        return [lengthFormatter stringFromValue:distance / 1609.34 unit:NSLengthFormatterUnitMile];
    }
}