- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我的 iOS 应用在不同的本地化版本(en_US
、en_AU
、ja_JP
等)中显示不同的货币(USD、JPY、AUD、EUR) ).
对于日语地区/语言(两者都在我的设备上设置),如果我:
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
fmt.numberStyle = NSNumberFormatterCurrencyStyle;
fmt.currencyCode = @"JPY";
NSString *labelText = [fmt stringFromNumber:@1000000];
我的标签文本是 ¥1,000,000
。但是,在日文和中文中,大于 10,000 的数字可能会写成 100 万日元
,这就是我想要的输出。
知道我可以编写什么代码来获得 100 万日元
作为输出吗?
我想避免在我的代码中检查语言环境/区域的逻辑 block ,但我觉得这就是我要面对的(例如,使用方法调用 fmt.multipler = @(1/10000)
将 1,000,000 除以 10,000 以获得正确的值)。
最佳答案
编辑:这里是最新的要点:https://gist.github.com/fjolnir/cd72ea39be1476023adf
旧线程,但我在寻找解决方案时遇到了它,所以我想我应该发布我的实现。
格式化程序本身不处理日元的放置,但在它之外很容易做到。 (如下例所示)
下面的预期输出是:
2015-03-11 18:00:13.376 LENumberFormatter[82736:3604947] 12億3,460万円
2015-03-11 18:00:13.377 LENumberFormatter[82736:3604947] 25円
-
@import Foundation;
@import ObjectiveC.message;
typedef NS_ENUM(NSUInteger, LENumberFormatterAbbreviationStyle) {
kLEAbbreviateShort, // 2.5m
kLEAbbreviateNormal // 2m 5k
};
@interface LENumberFormatter : NSNumberFormatter
@property(nonatomic) BOOL abbreviateLargeNumbers;
@property(nonatomic) LENumberFormatterAbbreviationStyle abbreviationStyle;
@end
@implementation LENumberFormatter
- (instancetype)init
{
if((self = [super init])) {
self.abbreviationStyle = [self _usingKanjiNumbers]
? kLEAbbreviateNormal
: kLEAbbreviateShort;
}
return self;
}
- (NSString *)stringForObjectValue:(id const)aObj
{
if(!_abbreviateLargeNumbers || ![aObj isKindOfClass:[NSNumber class]])
return [super stringForObjectValue:aObj];
// Copy ourselves to get format the partial digits using the settings on self
LENumberFormatter * const partialFormatter = [self copy];
partialFormatter.currencySymbol = @"";
if(_abbreviationStyle == kLEAbbreviateNormal)
partialFormatter.maximumFractionDigits = 0;
NSString *(^partialFormat)(NSNumber*) = ^(NSNumber *num) {
NSString *(*superImp)(struct objc_super*,SEL,NSNumber*) = (void*)&objc_msgSendSuper;
return superImp(&(struct objc_super) { partialFormatter, self.superclass }, _cmd, num);
};
double n = [aObj doubleValue];
BOOL const shortFormat = _abbreviationStyle == kLEAbbreviateShort;
NSDictionary * const separators = [self _localizedGroupingSeparators];
NSArray * const separatorExponents = [separators.allKeys sortedArrayUsingSelector:@selector(compare:)];
BOOL const currencySymbolIsSuffix = [self.positiveFormat hasSuffix:@"¤"];
NSMutableString * const result = currencySymbolIsSuffix || self.numberStyle != NSNumberFormatterCurrencyStyle
? [NSMutableString new]
: [self.currencySymbol mutableCopy];
NSUInteger significantDigits = 0;
NSNumber *lastExp = nil;
for(NSNumber *exp in separatorExponents.reverseObjectEnumerator) {
double divisor = pow(10, exp.shortValue);
if(divisor > n)
continue;
if(lastExp)
significantDigits += lastExp.doubleValue - exp.doubleValue;
lastExp = exp;
if(self.usesSignificantDigits && significantDigits >= self.maximumSignificantDigits)
break;
double partialNum = shortFormat
? n/divisor
: floor(n/divisor);
NSString * const digits = [self _groupRecursively] && ![exp isEqual:@0]
? [partialFormatter stringFromNumber:@(partialNum)]
: partialFormat(@(partialNum));
[result appendFormat:@"%@%@", digits, separators[exp]];
n = fmod(n, divisor);
if(shortFormat)
break; // Just use a float+first hit
// If we make it here, partialNum is integral and we can use log10 to find the number of digits
significantDigits += log10(partialNum) + 1;
partialFormatter.maximumSignificantDigits -= digits.length;
}
if(n > 0
&& !shortFormat
&& (!self.usesSignificantDigits || significantDigits < self.maximumSignificantDigits))
{
partialFormatter.maximumFractionDigits = self.maximumFractionDigits;
[result appendString:partialFormat(@(n))];
}
if(self.numberStyle == NSNumberFormatterCurrencyStyle && currencySymbolIsSuffix && self.currencySymbol)
[result appendString:self.currencySymbol];
return result.length > 0
? [result stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet]
: [super stringForObjectValue:aObj];
}
- (BOOL)_usingKanjiNumbers
{
return [self.locale.localeIdentifier rangeOfString:@"^(ja|zh)_"
options:NSRegularExpressionSearch].location != NSNotFound;
}
- (NSDictionary *)_localizedGroupingSeparators
{
if(self._usingKanjiNumbers)
return @{ @2: @"百", @3: @"千", @4: @"万", @8: @"億" };
else {
NSBundle * const bundle = [NSBundle bundleForClass:self.class];
return @{
@3: [bundle localizedStringForKey:@"thousandSuffix" value:@"k " table:nil],
@6: [bundle localizedStringForKey:@"millionSuffix" value:@"m " table:nil]
};
}
}
- (BOOL)_groupRecursively
{
// Return _usingKanjiNumbers if you want:
// 12億3千4百56万7千8百90
// Rather than:
// 1億2,3456万7千8百90
return NO;
}
- (instancetype)copyWithZone:(NSZone * const)aZone
{
LENumberFormatter * const copy = [super copyWithZone:aZone];
copy.abbreviateLargeNumbers = _abbreviateLargeNumbers;
copy.abbreviationStyle = _abbreviationStyle;
return copy;
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
LENumberFormatter * const f = [LENumberFormatter new];
f.locale = [NSLocale localeWithLocaleIdentifier:@"ja_JP"];
// f.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"];
f.numberStyle = NSNumberFormatterCurrencyStyle;
f.abbreviateLargeNumbers = YES;
f.abbreviationStyle = kLEAbbreviateNormal; // Automatic if using system locale
f.maximumSignificantDigits = 5;
f.usesSignificantDigits = YES;
// f.currencyCode = @"JPY";
// f.currencySymbol = @"¥";
if([f.locale.localeIdentifier hasPrefix:@"ja"]) {
f.positiveFormat = @"#,##0¤";
if([f.currencyCode isEqualToString:@"JPY"])
// We allow ourselves this special case because *日本円 just looks dumb
f.currencySymbol = @"円";
else
f.currencySymbol = [f.locale displayNameForKey:NSLocaleCurrencyCode
value:f.currencyCode];
}
NSLog(@"%@", [f stringFromNumber:@1234567890]);
NSLog(@"%@", [f stringFromNumber:@25]);
}
}
关于ios - 如何设置 NSNumberFormatter 以使用 "万"(日文/中文 10,000 标记)显示数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14471579/
我尝试过下面的代码,但只有“?”打印而不是 unicode 字符。 public static void main(String s[]){ char i1 = 0x0ABF; char i2
我有不同语言的字符串,主要是日语,当我尝试将它们打印为字符串时,它们显示得很好。但是,当我将其中许多添加到 python 列表中,然后打印出列表时,它们显示为如下文本:xe9 例如: string1
我目前正在开发一个包含日语和英语字符串的 mysql 数据库。 当前排序规则:utf8_general_ci。 我必须使用 LIKE %'japaneseWordHere'% 查询字符串中的日语单词。
目前,我正在使用这个正则表达式来检测日语标签和英语标签。\B([##][·・ー_0-90-9a-zA-Za-zA-Zぁ-んァ-ン一-龠]{1,24})(?=\W|$)规则是: Hashtag must
这对我来说似乎很难。我有将 CString 打印到文本文件的代码,但该值恰好是 Unicode(日语)。一旦命中此行,它下面的任何内容都不会被打印。 知道如何在文本文件中打印日语文本吗? #defin
我需要知道包含日文/中文字符的 unicode 字符串中有多少个可显示字符。 使问题变得非常明显的示例代码: # -*- coding: UTF-8 -*- str = '\xe7\x9d\xa1\x
请在 IE 中检查以下 js fiddle(我使用的是 10) http://jsfiddle.net/bF65u/1/ .inlineCol2 { width: 50%; } .op
我想向站点发送一个发布请求。下面的 python 代码工作正常。 # -*- encoding=utf-8 -*- import urllib, urllib2 url = "http://xxx.c
这个问题在这里已经有了答案: Unicode string literals in VBA (3 个回答) How to type Unicode currency character in Visu
我正在考虑使用 DejaVu 字体为 CJK 脚本创建 [Ruby-like][1] 字体。 但是我不确定,是否 DejaVu 提供/支持 CJK 字形? 否则,您是否推荐了另一种可重复使用的免费/开
我有一个图像目录,每个图像的名称中都有一个汉字。我正在尝试列出所有图像,在列表上循环,读取并显示每个图像。 图片路径类似于https://github.com/sirius-ai/LPRNet_Pyt
我想在 UITextView 中设置斜体字体样式,但斜体字体在 iOS 7 上不适用于中文/日文/韩文。有人能帮忙吗? 最佳答案 因为iOS上没有斜体中文字体,需要使用affine transform
如果我这样做: import pandas as pd pd.DataFrame( data=nr.random( (2,2) ), columns=[u'é',u'日本'] ).plot() 结果:
我希望能够识别中文、日文和韩文的书面字符,既可以作为一般语言,也可以作为分割语言。这些是原因: 将 CJK 识别为一个通用组:我正在制作一个垂直脚本蒙古语 TextView。为此,我需要将文本行旋转
我正在尝试对我正在处理的几个 URL 中的非 ASCII 字符进行 URL 转义(百分比编码)。我正在使用一个 Flash 应用程序,该应用程序从这些 URL 加载图像和声音剪辑等资源。由于文件名可以
我正在使用 PyPDF2 在 python 中读取 PDF 文件。虽然它适用于英语和欧洲语言(英语字母表),但图书馆无法阅读日语和中文等亚洲语言。我尝试了 encode('utf-8')、decode
我在 VBA 用户窗体中创建了一个 ListView 。 Listview 显示用户在 3 个文本框中插入的数据(单击“保存”按钮后)。用户可以在希伯来语中插入文本,但在 ListView 中,文本显
我有一个由 1 byte slice 假名组成的列表名称(示例 `゙),我通过 2 byte slice 假名 ji 进行搜索,但结果为零。你知道如何将搜索文本从 2 字节的假名转换为 1 字节吗?请
我的 iOS 应用在不同的本地化版本(en_US、en_AU、ja_JP 等)中显示不同的货币(USD、JPY、AUD、EUR) ). 对于日语地区/语言(两者都在我的设备上设置),如果我: NSNu
我们注意到,在 targetSdkVersion 28 期间,EditText 将在输入非英语 unicode(如中文、日语等)后倾向于“稍微下推”该行. 当代码为 targetSdkVersion
我是一名优秀的程序员,十分优秀!