iOS國際化

https://github.com/starainDou 歡迎點(diǎn)星

NSLocalizedString

Xcode中有本地化的內(nèi)置支持

  • NSLocalizedString的定義:
#define NSLocalizedString(key, comment) \
[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]

第一個參數(shù)key是從Localizable.strings這個文件中讀取對應(yīng)的key-value值食侮。
第二個參數(shù)comment可以是nil充活,可以是一段為空的字符串,也可以是對key的注釋。

  • 本地化字符串

添加語言支持

AddLanguage.png

建立String File文件霉祸,命名命名為“Localizable察净,生成一個Localizable.strings文件(名字不要其他的)

Localizable.png

選中新建的Localizable.strings文件掠手,點(diǎn)擊右邊的Localize抒巢,添加English和Chinese

Localize.png

在Localizable.strings(English) 文件中寫 "OK" = "OK";(不要忘記寫分號)
在Localizable.strings(Chinese) 文件中寫 "OK" = "確定";(不要忘記寫分號)

使用

define OKText NSLocalizedString(@"OK", nil)

如果你的strings文件名字不是Localizable而是自定義的話,如hel.strings介粘,那么你就得使用NSLocalizedStringFromTable()來讀取本地化字符串 NSLocalizedStringFromTable(@"hello",@"hel", nil)

如果不能添加語言支持(localizations--choose files and reference language to create...為空白)

打開工程配置殖氏,搜 /* Begin XCBuildConfiguration section */
在之前添加段落

/* Begin PBXVariantGroup section /
4C0E56D11F09E6B900583071 /
Localizable.strings / = {
isa = PBXVariantGroup;
children = (
4C0E56D01F09E6B900583071 /
en /,
4C0E56D21F09E6C200583071 /
zh-Hans /,
);
name = Localizable.strings;
sourceTree = "<group>";
};
ABCB97AC1D71D063000DEBEF /
LaunchScreen.storyboard / = {
isa = PBXVariantGroup;
children = (
ABCB97AD1D71D063000DEBEF /
Base /,
4C0E56CC1F09E37B00583071 /
zh-Hans /,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/
End PBXVariantGroup section */

然后添加直接添加Localizable.strings,方法見上姻采,不考慮別的問題雅采,然后回到配置文件搜索
/* Localizable.strings in Resources /
復(fù)制ID
搜/
Begin PBXVariantGroup section /,將/ Localizable.strings */ 前面的ID 替換保存即可

XCBuildConfiguration

封裝的工具,在APP內(nèi)切換語言

你可以用黑魔法為全局添加婚瓜,不過需要處理很多特殊情況宝鼓。

DDYLanguageTool.h

/**
 *  語言國際化使用方式
 *  1.AppDelegata中 -application:didFinishLaunchingWithOptions: 里設(shè)置默認(rèn)(初始化即可)   [DDYLanguageTool sharedManager];
 *  2.選擇語言后 [[DDYLanguageTool sharedManager] ddy_SetLanguage:_selectLanguage callback:nil];
 */

#import <Foundation/Foundation.h>

/** 英漢雙語 */
#if TARGET_IPHONE_SIMULATOR
#define DDYStr(Chinese,English) [DDYCurrentLanguage isEqualToString:IOS_9_LATER?@"zh-Hans-US":@"zh-Hans"] ? Chinese : English
#elif TARGET_OS_IPHONE
#define DDYStr(Chinese,English) [DDYCurrentLanguage isEqualToString:IOS_9_LATER?@"zh-Hans-CN":@"zh-Hans"] ? Chinese : English
#endif


extern NSErrorDomain DDYLanguageErrorDomain;
#define kDDYLanguageErrorSuccess       0  // 設(shè)置語言成功
#define kDDYLanguageErrorUnknown      -1  // 未知錯誤
#define kDDYLanguageErrorNil          -2  // 語言為空
#define kDDYLanguageErrorNotSupport   -3  // 不支持的語言

static NSString *const DDY_CN  = @"zh-Hans";
static NSString *const DDY_EN  = @"en";

@interface DDYLanguageTool : NSObject

/** 單例對象 */
+ (instancetype)sharedManager;

/** 獲取當(dāng)前語言 */
- (NSString *)localLanguage;

/** 切換語言(漢英時) */
- (void)changeLanguage;

/** 設(shè)置語言(較多語言支持時) */
- (void)ddy_SetLanguage:(NSString *)language callback:(void (^)(NSError *error))callback;

@end

DDYLanguageTool.m


#import "DDYLanguageTool.h"
#import <objc/runtime.h>

#define DDYLanguageSet @"DDYLanguageSet"

NSErrorDomain DDYLanguageErrorDomain = @"DDYLanguageErrorDomain";


//----------------------- NSBundle子類 -----------------------//
static const char _bundle = 0;

@interface DDYBundleExt : NSBundle

@end

@implementation DDYBundleExt

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {
    NSBundle *bundle = objc_getAssociatedObject(self, &_bundle);
    return bundle ? [bundle localizedStringForKey:key value:value table:tableName] : [super localizedStringForKey:key value:value table:tableName];
}

@end


//------------------------ 語言設(shè)置工具類 -----------------------//
@implementation DDYLanguageTool


#pragma mark - 單例對象
static DDYLanguageTool *_instance;

+ (instancetype)sharedManager {
    return [[self alloc] init];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone {
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
}

#pragma mark 初始化
- (instancetype)init {
    if (self = [super init]) {
        NSString *currLanguage = DDYUserDefaultsGet(DDYLanguageSet);
        // 默認(rèn)語言(中英)
        if (!currLanguage) {
            currLanguage = DDYStr(DDY_CN, DDY_EN);
        }
        DDYUserDefaultsSet(currLanguage, DDYLanguageSet)
        [DDYUserDefaults synchronize];
        [self setLanguage:currLanguage];
    }
    return self;
}

#pragma mark 獲取當(dāng)前語言
- (NSString *)localLanguage {
    return DDYUserDefaultsGet(DDYLanguageSet);
}

#pragma mark 切換語言(中英時)
- (void)changeLanguage {
    [DDYUserDefaults setObject:[DDYUserDefaultsGet(DDYLanguageSet) isEqualToString:DDY_CN] ? DDY_EN : DDY_CN forKey:DDYLanguageSet];
    [DDYUserDefaults synchronize];
}

#pragma mark 設(shè)置語言(較多語言支持時)
- (void)ddy_SetLanguage:(NSString *)language callback:(void (^)(NSError *error))callback {
    if ([language ddy_blankString]) {
        if (callback) callback([NSError errorWithDomain:DDYLanguageErrorDomain code:kDDYLanguageErrorNil userInfo:@{@"reason":@"設(shè)置的語言不能為空"}]);
    } else {
        [self setLanguage:language];
        [DDYUserDefaults setObject:language forKey:DDYLanguageSet];
        [DDYUserDefaults synchronize];
        if (callback) callback([NSError errorWithDomain:DDYLanguageErrorDomain code:kDDYLanguageErrorSuccess userInfo:@{@"reason":@"設(shè)置成功"}]);
    }
}

#pragma mark 私有方法 設(shè)置語言
- (void)setLanguage:(NSString *)language {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        object_setClass([NSBundle mainBundle], [DDYBundleExt class]);
    });
    
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

碼農(nóng)不易,點(diǎn)個星星支持下吧 DDYLanguageTool

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闰渔,一起剝皮案震驚了整個濱河市席函,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冈涧,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件正蛙,死亡現(xiàn)場離奇詭異督弓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)乒验,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門愚隧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锻全,你說我怎么就攤上這事狂塘。” “怎么了鳄厌?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵荞胡,是天一觀的道長。 經(jīng)常有香客問我了嚎,道長泪漂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任歪泳,我火速辦了婚禮萝勤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘呐伞。我一直安慰自己敌卓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布伶氢。 她就那樣靜靜地躺著趟径,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鞍历。 梳的紋絲不亂的頭發(fā)上舵抹,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天,我揣著相機(jī)與錄音劣砍,去河邊找鬼惧蛹。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的香嗓。 我是一名探鬼主播迅腔,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼靠娱!你這毒婦竟也來了沧烈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤像云,失蹤者是張志新(化名)和其女友劉穎锌雀,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迅诬,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腋逆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了侈贷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惩歉。...
    茶點(diǎn)故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖俏蛮,靈堂內(nèi)的尸體忽然破棺而出撑蚌,到底是詐尸還是另有隱情,我是刑警寧澤搏屑,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布争涌,位于F島的核電站,受9級特大地震影響睬棚,放射性物質(zhì)發(fā)生泄漏第煮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一抑党、第九天 我趴在偏房一處隱蔽的房頂上張望包警。 院中可真熱鬧,春花似錦底靠、人聲如沸害晦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壹瘟。三九已至,卻和暖如春鳄逾,著一層夾襖步出監(jiān)牢的瞬間稻轨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工雕凹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留殴俱,地道東北人政冻。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像线欲,于是被迫代替她去往敵國和親明场。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Demo同步更新到Swift2.3本文地址: http://mokai.me/iOS-i18n.html 在真正...
    _GKK_閱讀 5,793評論 13 55
  • 國際化(Internationalization 李丰,簡寫為I18N)的作用是防止將本土文化信息寫死仔應(yīng)用里(所謂本...
    西西西瓜啊閱讀 11,321評論 23 15
  • ** 原文發(fā)表在:https://www.xiaolei0808.com/2016/04/24/Localized...
    金小白先生閱讀 17,552評論 16 90
  • 之前公司的app可能要在島國和東南亞地區(qū)使用苦锨,所以最合理的方法就是--國際化。 寫這篇文章也是為一個妹子寫的(咦~...
    倫敦鄉(xiāng)下的小作家閱讀 796評論 4 4
  • 一趴泌、簡介 所謂國際化就是讓你的APP能在不同國家的人們都能看懂舟舒,即讓你APP中的語言跟隨系統(tǒng)變化,若系統(tǒng)當(dāng)前語言是...
    小道蕭兮閱讀 4,058評論 0 4