NSLengthFormatter的getStringFromMeters:方法是否仅支持英里/公里单位?

5
我正在使用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米,则格式化的距离始终以码或米(取决于语言环境)显示。
例如,如果距离为450.0,则格式化字符串将是492.7 yd或450 m。
我该如何调整NSLengthFormatter,使其仅返回英里/千米的距离字符串?

你尝试过设置不同的 numberFormatter 并尝试调整 NSNumberFormatter 的不同属性吗? - luk2302
是的,我试过设置小数位数和舍入模式,但对测量输出没有影响。我仍在查看属性,但希望有人已经实现了相同的功能。 - ZeMoon
参见这个答案 - Droppy
@Droppy 谢谢,这基本上就是我想要的(并且必须实现)。但为了回答问题,如何使用iOS 8中提供的新类NSLengthFormatter来实现相同的结果? - ZeMoon
我不知道,但你想要的是格式化<number><unit>,这可以使用NSNumberFormatter轻松完成。 - Droppy
4个回答

10

这是我最终使用的内容:

-(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)
        }
    }

6
好的,谢谢。我尊重地不同意Sulthan的观点——在地图应用中,我认为您确实希望坚持使用一个单位,以便用户不必在脑中进行转换。那家餐厅距离这里有 20 英里,或者距离这里有 0.3 英里——请不要显示英尺或码,非常感谢。 :) - SimplGy

3

似乎没有办法退出这种行为。说实话,从用户体验的角度来看,您的要求并不是很常见。

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

实际上,设计一个可以强制执行特定单位的API非常困难,因为基本单位取决于当前语言环境。

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

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

但是你需要自己处理语言环境和比例尺的转换以及单位转换(参见Objective c string formatter for distances)。


2
这就是我所做的。检查一下答案。你是对的,这个需求并不是很常见。然而,我的客户不喜欢距离以码为单位显示。在使用英制度量衡系统的国家,我相信人们看到以米为格式显示的距离也没有问题。 - ZeMoon
2
@ZeMoon 你会惊讶地发现,美国有很多人根本不理解公制系统 :) - Sulthan
地图上和路上的距离(当使用公制系统时)总是以千米为单位,因此这实际上是一个非常普遍的要求。 - lenooh
@lenooh 不是这样的。我住在一个使用公制系统的国家,道路上和地图导航中到处都是以米为单位的距离。一旦距离足够小,通常会使用更小的单位。 - Sulthan
3
对于不使用公制系统的人来说,这实际上是一个非常普遍的要求(是的,我知道...)。在公制系统中,从千米到米是有意义的,但如果你按照同样的逻辑,你会从英里到码再到英尺。通常你不想在道路距离中使用码,也不想显示5000英尺,而是要显示0.9英里。 - Ludovic Landry

2

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

在公制系统中,从千米到米等转换是有意义的。如果你按照同样的逻辑使用英制系统,你会从英里到码再到英尺。

通常情况下,例如在路程距离上,你不希望使用码,也不想显示5000英尺,而是要显示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)
    }
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接