app ios 内切换语言
2018-04-22 21:16:00 weixin_34281477 阅读数 10

  继上一篇文字,这次写一下app内切换语言。上一篇传送门iOS语言国际化
  上周一个星期都不在状态,原来是感冒了,眼睛也不舒服,还上火,我丢· 我是干了什么啊· 心累。。。。。

回归正题

 我的实现是这样的。
 废话不多说,先上代码。(不对 先上图)


3339381-c6c783599ef36a8e.gif
假装模仿一下支付宝切换语言
+ (void)initUserLanguage{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSString *string = [def valueForKey:UserLanguage];
    if(string.length == 0)
    {
        //获取系统当前语言版本(中文zh-Hans,英文en)
        NSArray *languages = [NSLocale preferredLanguages];
        NSString *current = [languages objectAtIndex:0];
        string = [self languageFormat:current];
        //个人需求 目前就两种语言
        if (![string isEqualToString:@"zh-Hans"]&&![string isEqualToString:@"en"]) {
            string=@"en";
        }
        [def setValue:current forKey:UserLanguage];
        [def synchronize];
        
    }
    //获取文件路径
    NSString *path = [[NSBundle mainBundle] pathForResource:[self languageFormat:string] ofType:@"lproj"];
    
    bundle = [NSBundle bundleWithPath:path];//生成bundle
}

///语言和语言对应的.lproj的文件夹前缀不一致时在这里做处理
+ (NSString *)languageFormat:(NSString*)language {
    if([language rangeOfString:@"zh-Hans"].location != NSNotFound)
    {
        return @"zh-Hans";
    }
    else if([language rangeOfString:@"zh-Hant"].location != NSNotFound)
    {
        return @"zh-Hant";
    }
    else
    {
        //字符串查找
        if([language rangeOfString:@"-"].location != NSNotFound) {
            //除了中文以外的其他语言统一处理@"ru_RU" @"ko_KR"取前面一部分
            NSArray *ary = [language componentsSeparatedByString:@"-"];
            if (ary.count > 1) {
                NSString *str = ary[0];
                return str;
            }
        }
    }
    return language;
}

首先初始化你的语言,存储到偏好设置。取不到对应的key 就用系统的语言。这边对获取到的语言做了一点小处理。
你可以在AppDelegate里初始化一下。

+ (NSString *)getStringByKey:(NSString *)key
{
    if (![[LocalizationManager bundle] localizedStringForKey:key value:@"" table:nil]) {
        return [[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil];
    }
    return [[LocalizationManager bundle] localizedStringForKey:key value:@"" table:nil];
}

需要语言国际化的字符串用这个方法来取值。

最后就是改变语言了。

+ (void)setUserlanguage:(NSString *)language{
    
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    
    //1.第一步改变bundle的值
    NSString *path = [[NSBundle mainBundle] pathForResource:[self languageFormat:language] ofType:@"lproj" ];
    
    bundle = [NSBundle bundleWithPath:path];
    
    //2.持久化
    [def setValue:language forKey:UserLanguage];
    
    [def synchronize];
    //重置app
    [self resetRootViewController];
}

重置app就看个人需求了·做了一个小 Demo,假装模仿一下支付宝设置多语言。可以简单参考参考,很简单的啦。

转载于:https://www.jianshu.com/p/3560b11f3e9a

2018-04-22 21:16:00 weixin_34254823 阅读数 36

  继上一篇文字,这次写一下app内切换语言。上一篇传送门iOS语言国际化
  上周一个星期都不在状态,原来是感冒了,眼睛也不舒服,还上火,我丢· 我是干了什么啊· 心累。。。。。

回归正题

 我的实现是这样的。
 废话不多说,先上代码。(不对 先上图)


3339381-c6c783599ef36a8e.gif
假装模仿一下支付宝切换语言
+ (void)initUserLanguage{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSString *string = [def valueForKey:UserLanguage];
    if(string.length == 0)
    {
        //获取系统当前语言版本(中文zh-Hans,英文en)
        NSArray *languages = [NSLocale preferredLanguages];
        NSString *current = [languages objectAtIndex:0];
        string = [self languageFormat:current];
        //个人需求 目前就两种语言
        if (![string isEqualToString:@"zh-Hans"]&&![string isEqualToString:@"en"]) {
            string=@"en";
        }
        [def setValue:current forKey:UserLanguage];
        [def synchronize];
        
    }
    //获取文件路径
    NSString *path = [[NSBundle mainBundle] pathForResource:[self languageFormat:string] ofType:@"lproj"];
    
    bundle = [NSBundle bundleWithPath:path];//生成bundle
}

///语言和语言对应的.lproj的文件夹前缀不一致时在这里做处理
+ (NSString *)languageFormat:(NSString*)language {
    if([language rangeOfString:@"zh-Hans"].location != NSNotFound)
    {
        return @"zh-Hans";
    }
    else if([language rangeOfString:@"zh-Hant"].location != NSNotFound)
    {
        return @"zh-Hant";
    }
    else
    {
        //字符串查找
        if([language rangeOfString:@"-"].location != NSNotFound) {
            //除了中文以外的其他语言统一处理@"ru_RU" @"ko_KR"取前面一部分
            NSArray *ary = [language componentsSeparatedByString:@"-"];
            if (ary.count > 1) {
                NSString *str = ary[0];
                return str;
            }
        }
    }
    return language;
}

首先初始化你的语言,存储到偏好设置。取不到对应的key 就用系统的语言。这边对获取到的语言做了一点小处理。
你可以在AppDelegate里初始化一下。

+ (NSString *)getStringByKey:(NSString *)key
{
    if (![[LocalizationManager bundle] localizedStringForKey:key value:@"" table:nil]) {
        return [[NSBundle mainBundle] localizedStringForKey:key value:@"" table:nil];
    }
    return [[LocalizationManager bundle] localizedStringForKey:key value:@"" table:nil];
}

需要语言国际化的字符串用这个方法来取值。

最后就是改变语言了。

+ (void)setUserlanguage:(NSString *)language{
    
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    
    //1.第一步改变bundle的值
    NSString *path = [[NSBundle mainBundle] pathForResource:[self languageFormat:language] ofType:@"lproj" ];
    
    bundle = [NSBundle bundleWithPath:path];
    
    //2.持久化
    [def setValue:language forKey:UserLanguage];
    
    [def synchronize];
    //重置app
    [self resetRootViewController];
}

重置app就看个人需求了·做了一个小 Demo,假装模仿一下支付宝设置多语言。可以简单参考参考,很简单的啦。

2018-03-14 13:18:41 Haitao0692 阅读数 301

开发java的时候要求实现语言国际化,在java中用了i18来进行处理,移动端也可以进行处理:

方法可以有以下两种:

方案一:在原国际化版本的基础上做修改,在info.plist文件中新增key="appLanguage"的键值对,保存用户设定的语言类别。通过切换语言类别来改变语言。(例子:微信)
优点:之前有国际化操作的基础,执行起来并不复杂。
缺点:切换完语言后,需要重新创建app keywindow的跟控制器,会有个跳转的过程,用户体验不好。
方案二:切换语言后,发送通知,每个控制器收到通知后,更改语言。(例子:新浪微博)
优点:很自然的切换语言,选择语言后即可切换,不需要重置根控制器,用户体验好。
缺点:每个控制器都得注册接收通知,工作量太大,而且storyboard也得单独处理。

两种方法都可实现,我们来看方案一:

中英切换,就是让App根据自身设置的语言去读取对应的国际化文件。在NSUserDefault中有一个字段:"AppleLanguages",这个字段就是负责存储App语言的字段,默认这个字段会根据系统语言去变动,中文系统他就存储中文,英文系统就存储英文。

.h文件:

// NTVLocalized.h

#import <Foundation/Foundation.h>

static NSString * const AppLanguage = @"appLanguage";

@interface NTVLocalized : NSObject
+ (NTVLocalized *)sharedInstance;

//初始化多语言功能
- (void)initLanguage;

//当前语言
- (NSString *)currentLanguage;

//设置要转换的语言
- (void)setLanguage:(NSString *)language;

//设置为系统语言
- (void)systemLanguage;

@end


.m文件:

// NTVLocalized.m

#import "NTVLocalized.h"

@implementation NTVLocalized
+ (NTVLocalized *)sharedInstance {
    static NTVLocalized *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[NTVLocalized alloc] init];
    });
    return instance;
}

- (void)initLanguage{
    NSString *language=[self currentLanguage];
    if (language.length>0) {
        NSLog(@"自设置语言:%@",language);
    }else{
        [self systemLanguage];
    }
}

- (NSString *)currentLanguage{
    NSString *language=[[NSUserDefaults standardUserDefaults]objectForKey:AppLanguage];
    return language;
}

- (void)setLanguage:(NSString *)language{
    [[NSUserDefaults standardUserDefaults] setObject:language forKey:AppLanguage];
}

- (void)systemLanguage{
    NSString *languageCode = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"][0];
    NSLog(@"系统语言:%@",languageCode);
    if([languageCode hasPrefix:@"zh-Hans"]){
        languageCode = @"zh-Hans";//简体中文
    }else if([languageCode hasPrefix:@"en"]){
        languageCode = @"en";//英语
    }
    [self setLanguage:languageCode];
}

@end


当语言设置完成后,需要重新设置keywindow的rootViewController才可以实现语言的切换。
然而这样设置后,我们发现只有NSLocalizedString(key, comment)设置的语言才能正常显示我们需要的语言,storyBoard和xib配置的页面语言不跟着切换。

设置AppleLanguages字段的话,只会在下次启动App才会生效,在App启动后就已经生成了一个Bundle,里面识别好了对应着AppleLanguages的国际化文件,在App运行期间设置这个字段,是不生效的,所以我们去修改这个Bundle,写一个NSBundle的扩展。

// NSBundle+language.m

#import "NSBundle+language.h"
#import <objc/runtime.h>

static const char _bundle = 0;

@interface BundleEx : NSBundle

@end

@implementation BundleEx

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

@implementation NSBundle (Language)

+ (void)setLanguage:(NSString *)language {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        object_setClass([NSBundle mainBundle], [BundleEx class]);
    });
    
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end


// NSBundle+language.h

#import <Foundation/Foundation.h>

@interface NSBundle (language)
// 设置语言
+ (void)setLanguage:(NSString *)language;
@end


重新写一下设置语言的方法:

- (void)setLanguage:(NSString *)language{
    [NSBundle setLanguage:language];
    [[NSUserDefaults standardUserDefaults] setObject:language forKey:AppLanguage];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

修改bundle后可实现语言的全部切换,不需要重启APP

若有疑问咨询QQ:1147726728

2014-06-29 23:46:52 d200820205051 阅读数 1739

//国际化

#define AppLanguage @"myAppLanguage"

#define UserDefaultLanguage ([[NSUserDefaults standardUserDefaults] objectForKey:AppLanguage]? \

[[NSUserDefaults standardUserDefaults] objectForKey:AppLanguage]:@"zh-Hans")

#define CustomLocalizedString(key, comment) \

[[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@",UserDefaultLanguage] ofType:@"lproj"]] localizedStringForKey:(key) value:comment table:nil]

放在项目中的.pch文件里可以全局使用

根目录创建文件夹en.lproj、zh-Hans.lproj(英文、中文简体)

在每个文件夹内创建Localizable.strings文件并写入:

"about_us"="关于我们";

调用:

self.versionLabel.text =CustomLocalizedString(@"about_us",@"当前版本");

语言切换自己写个按钮切换"en"和"zh-Hans"存到UserDefault里,key是 #define的AppLanguage就可以了


点下支持下我-->网址导航


2018-10-11 16:10:00 weixin_34289454 阅读数 88

想要实现App内的语言切换功能,那么首先要创建国际化语言文件,用于存储对应语言显示的文本。
1、创建国际化语言文件
command+N,选择Other里面的Empty文件。

11696239-6ca7ff14c666843e.png
image.png

我们将其命名为Localizable.strings
选中刚才创建的文件,在其右侧的的属性栏中点击Localize按钮。
11696239-dbd40bf14cfdf23f.png
image.png

2、设置项目需要支持的语言
选中project--->info--->Localization。
我们会发现里面默认有一个英语,我们可以点击左下角的➕号添加支持的语言。
11696239-ddab1f3e50348245.png
image.png

点击+号,选择简体中文。
11696239-4a2a10e4d8b7f9c2.png
image.png

默认全选,点击完成即可:
11696239-a865ad4feb55a774.png
image.png

这时我们展开Localizable.strings、Main.storyboard和LaunchScreen.storyboard,会看到多了一些文件。
11696239-c727a26cbeb68d7a.png
image.png

3、文本国际化
11696239-0060ac281ae61929.png
英文语言文件.png

11696239-8bb34b7aabf80ea6.png
中文语言文件.png

大家看这个可能会有疑问,不知道是什么意思。
"首页" = "首页";
"首页" = "Homepage";
其实这两个是一个文本的不同语言的展示。“=”号左面的相当于key值;“=”号右面的相当于value值。不过为了使用方便,更容易理解,我这里直接使用了中文的内容作为key值。
使用方法的话:NSLocalizedString(@"首页", nil);
这样,在中文语言的时候返回“首页”(中文),在英文语言中返回“ Homepage”(英文)。

如果你是用xib或者Storyboard展示文本的话,想要文本国际化展示的话,需要另外的方法。

11696239-edb7374ca820a3cf.png
image.png

首先选中xib或者Storyboard,选中需要支持的语言。

11696239-2360373fb95319bb.png
中文

11696239-2ffd02ec09e6d523.png
英文

我们可以看到对应的文件里面有对应的显示文本。如果要想xib随着设置的不同语言展示不同的文本的话,可以在这两个文件中修改。

4、本地存储语言设置
使用NSUserDefaults存储本地语言设置。
直接上代码:这是一位大神分享的代码,我复制了一份,效果很不错,看原文请点这里原文.

存储、获取、重置本地语言设置

#import <Foundation/Foundation.h>

@interface UWConfig : NSObject

/**
 用户自定义使用的语言,当传nil时,等同于resetSystemLanguage
 */
@property (class, nonatomic, strong, nullable) NSString *userLanguage;

/**
 重置系统语言
 */
+ (void)resetSystemLanguage;

@end
#import "UWConfig.h"

static NSString *const UWUserLanguageKey = @"UWUserLanguageKey";
#define STANDARD_USER_DEFAULT  [NSUserDefaults standardUserDefaults]

@implementation UWConfig

+ (void)setUserLanguage:(NSString *)userLanguage
{
    //跟随手机系统
    if (!userLanguage.length) {
        [self resetSystemLanguage];
        return;
    }
    //用户自定义
    [STANDARD_USER_DEFAULT setValue:userLanguage forKey:UWUserLanguageKey];
    [STANDARD_USER_DEFAULT setValue:@[userLanguage] forKey:@"AppleLanguages"];
    [STANDARD_USER_DEFAULT synchronize];
}

+ (NSString *)userLanguage
{
    return [STANDARD_USER_DEFAULT valueForKey:UWUserLanguageKey];
}

/**
 重置系统语言
 */
+ (void)resetSystemLanguage
{
    [STANDARD_USER_DEFAULT removeObjectForKey:UWUserLanguageKey];
    [STANDARD_USER_DEFAULT setValue:nil forKey:@"AppleLanguages"];
    [STANDARD_USER_DEFAULT synchronize];
}

@end

切换bundle

#import <Foundation/Foundation.h>

@interface NSBundle (UWUtils)

+ (BOOL)isChineseLanguage;

+ (NSString *)currentLanguage;

@end
#import "NSBundle+UWUtils.h"
#import "UWConfig.h"
#import <objc/runtime.h>

@interface UWBundle : NSBundle

@end

@implementation NSBundle (UWUtils)

+ (BOOL)isChineseLanguage
{
    NSString *currentLanguage = [self currentLanguage];
    if ([currentLanguage hasPrefix:@"zh-Hans"]) {
        return YES;
    } else {
        return NO;
    }
}

/*
 *  设置默认语言类型
 */
+ (NSString *)currentLanguage
{
//    return [UWConfig userLanguage] ? : [NSLocale preferredLanguages].firstObject;
    return [UWConfig userLanguage] ? : @"zh-Hans";
}

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //动态继承、交换,方法类似KVO,通过修改[NSBundle mainBundle]对象的isa指针,使其指向它的子类UWBundle,这样便可以调用子类的方法;其实这里也可以使用method_swizzling来交换mainBundle的实现,来动态判断,可以同样实现。
        object_setClass([NSBundle mainBundle], [UWBundle class]);
    });
}

@end


@implementation UWBundle

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    if ([UWBundle uw_mainBundle]) {
        return [[UWBundle uw_mainBundle] localizedStringForKey:key value:value table:tableName];
    } else {
        return [super localizedStringForKey:key value:value table:tableName];
    }
}

+ (NSBundle *)uw_mainBundle
{
    if ([NSBundle currentLanguage].length) {
        NSString *path = [[NSBundle mainBundle] pathForResource:[NSBundle currentLanguage] ofType:@"lproj"];
        if (path.length) {
            return [NSBundle bundleWithPath:path];
        }
    }
    return nil;
}

@end

5、使用方式
当切换app语言的时候,先存储本地语言的设置;然后刷新界面即可。

- (IBAction)simplifiedChinese:(UIButton *)sender {
    [UWConfig setUserLanguage:@"zh-Hans"];
    
    // 刷新界面
    [self reloadTabBarViewController];
}

- (IBAction)english:(UIButton *)sender {
    [UWConfig setUserLanguage:@"en"];
    
    // 刷新界面
    [self reloadTabBarViewController];
}

刷新界面
我这儿是直接刷新了tabBar控制器。

- (void)reloadTabBarViewController {
    
    UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    
    UITabBarController *tbc = [storyBoard instantiateInitialViewController];
    // 跳转到个人中心页面(即设置语言的那个tabBarItem)
    tbc.selectedIndex = self.tabBarController.selectedIndex;
    
    // 创建设置页面
    UIViewController *settingVC = [storyBoard instantiateViewControllerWithIdentifier:@"setting"];
    settingVC.hidesBottomBarWhenPushed = YES;
    
    // 创建语言选择界面
    FiFLanguageController *languageVC = [storyBoard instantiateViewControllerWithIdentifier:@"chooseLanguage"];
    languageVC.hidesBottomBarWhenPushed = YES;
    
    UINavigationController *nvc = tbc.selectedViewController;
    
    // 备用
    NSMutableArray *vcs = nvc.viewControllers.mutableCopy;
    [vcs addObjectsFromArray:@[settingVC, languageVC]];
    
    //解决奇怪的动画bug。异步执行
    dispatch_async(dispatch_get_main_queue(), ^{
        
        //注意刷新rootViewController的时机,在主线程异步执行
        //先刷新rootViewController
        [UIApplication sharedApplication].keyWindow.rootViewController = tbc;
        
        //然后再给个人中心的nvc设置viewControllers
        nvc.viewControllers = vcs;
    });
}

ok,结束了!

没有更多推荐了,返回首页