NSLengthFormatter获取stringFromMeters:仅以英里/公里为单位

时间:2015-06-20 07:41:13

标签: ios objective-c cllocationdistance

我使用NSLengthFormatter类格式化用户与某个目的地之间的距离。

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米,则格式化的距离始终以码或米显示(取决于区域设置)。

EG。如果距离= 450.0,格式化的字符串将是492.7码或450米。

如何调整NSLengthFormatter以仅以英里/公里为单位返回距离字符串?

3 个答案:

答案 0 :(得分:8)

这就是我最终使用的内容:

-(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];
    }
}

答案 1 :(得分:3)

似乎没有办法选择退出此行为。说实话,从UX的角度来看,您的要求并不常见。

请注意,meter是基本单位,而不是kilometer(千米)。通常,显示10 meters比显示0.01 kilometers更受欢迎。它对用户来说更友好。

考虑到基本单元依赖于当前区域设置,实际上很难设计一个强制执行特定单元的API。

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

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

但你必须处理语言环境和缩放&amp;单位转换(参见Objective c string formatter for distances

答案 2 :(得分:0)

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

在公制中,从公里到米等都是有意义的。如果对英制遵循相同的逻辑,则将从英里到码到英尺。

通常,您不想使用“码”作为道路距离,并且您不想显示5,000 ft但显示0.9英里(实际上Google Maps以英尺为单位显示最大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)
    }
}