网上看到一些关于:“根据App设置”加载本地化资源的文章。但都只讲到了界面文字的本地化,却没有关于图标,视频等其他资源的本地化实现方式。
今天,正好我们的App中需要这种功能,便自己实现了一套。里面除了“文字”外,还实现了“图像”,“plist”的加载。其他如“视频”,“json”等文件可调用:BALocalizedFile方法来加载。
这里就把实现的代码贴出来,便于大家参考。
头文件:BALocalized.h
//
// BALocalized.h
// mhMoney
//
// Created by wuzhigang on 2024/2/27.
//
#import <Foundation/Foundation.h>
#define kAppLanguage @"AppLanguage"
//获取系统语言字符串
NSString* BALocalizedSystemLanguage(void);
//保存App语言设置到配置文件中。
//传入:
//language:"en", "zh-Hans"等本地化目录名
void BALocalizedSaveLanguage(NSString *language);
//从配置文件读取当前App语言配置。
//返回:
//language:"en", "zh-Hans"等本地化目录名
NSString* BALocalizedReadLanguage(void);
//本地化Bundle获取。
//返回:本地化Bundle
NSBundle* BALocalizedBundle(void);
//返回本地化字符串
//传入:
//key:字符串Key
//table:table
//返回:
//Key对应的本地化字符串
NSString* BALocalizedString(NSString* key, NSString* table);
//初始化本地化语言
//传入:
//language:"en", "zh-Hans"等本地化目录名
void BALocalizedInitLanguage(NSString *language);
//获取本地化资源文件
//传入:
//fileName:文件名
//type:文件扩展名,如"plist", "png", "mp4", "wav"等。
//返回
//本地化的文件路径
NSString* BALocalizedFile(NSString* fileName, NSString* type);
//获取本地化plist
//传入:
//fileName:文件主名
//type:文件扩展名,如"plist", "png", "mp4", "wav"等。
//返回
//plist内容
NSArray* BALocalizedPlist(NSString* fileName);
//获取本地化图片
//传入:
//imageName:图片主名
//返回
//UIImage对象
//注意:其他图片类型,修改该方法内部type值即可。如“jpg"等。
UIImage* BALocalizedImage(NSString* imageName);
实现文件:BALocalized.m
//
// BALocalized.m
// mhMoney
//
// Created by wuzhigang on 2024/2/27.
//
#import "BALocalized.h"
static NSBundle *staticLocalizedBundle;
NSString* BALocalizedSystemLanguage(void){
NSArray *languages = [NSLocale preferredLanguages]; //系统偏好语言
NSString *language = languages.firstObject;
if ([language hasPrefix:@"zh-Hans"]) {
BALocalizedSaveLanguage(@"zh-Hans");
return @"zh-Hans";
}
return @"en";
}
void BALocalizedSaveLanguage(NSString *language){
if (!language || language.length == 0){
language = @"en";
}
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (!userDefaults)
return;
[userDefaults setValue:language forKey:kAppLanguage];
}
NSString* BALocalizedReadLanguage(void){
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (!userDefaults)
return BALocalizedSystemLanguage();
NSString *language = [userDefaults valueForKey:kAppLanguage];
if (!language || language.length == 0){
return BALocalizedSystemLanguage();
}
return language;
}
void BALocalizedInitLanguage(NSString *language){
staticLocalizedBundle = nil;
BALocalizedSaveLanguage(language);
}
NSBundle* BALocalizedBundle(void){
if (staticLocalizedBundle)
return staticLocalizedBundle;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *language = userDefaults ? [userDefaults valueForKey:kAppLanguage] : nil;
if (!language || language.length == 0) {
return nil;
}
NSString *path = [NSBundle.mainBundle pathForResource:language ofType:@"lproj"];
if (!path || path.length == 0)
return nil;
NSBundle *bundle = [NSBundle bundleWithPath:path];
staticLocalizedBundle = bundle ? bundle : NSBundle.mainBundle;
return staticLocalizedBundle;
}
NSString* BALocalizedString(NSString* key, NSString* table){
NSBundle *bd = BALocalizedBundle();
if (!bd)
return nil;
return [bd localizedStringForKey:key value:nil table:table];
}
NSString* BALocalizedFile(NSString* fileName, NSString* type){
if (!fileName || fileName.length == 0)
return nil;
if (!type || type.length == 0)
return nil;
NSBundle *bd = BALocalizedBundle();
if (!bd)
return nil;
return [bd pathForResource:fileName ofType:type];
}
NSArray* BALocalizedPlist(NSString* fileName){
NSString *filePath = BALocalizedFile(fileName, @"plist");
if (!filePath || filePath.length == 0)
return nil;
return [[[NSArray alloc] initWithContentsOfFile:filePath] autorelease];
}
UIImage* BALocalizedImage(NSString* imageName){
if (@available(iOS 17.0, *)){
NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:BALocalizedReadLanguage()] autorelease];
UIImageConfiguration *config = [UIImageConfiguration configurationWithLocale:locale];
//非Assets资源本地化放在各个语言的bundle中,而Assets中的本地化放在Main Bundle中。
//故先从非Assets中加载,没有找到再从主bundle中加载。
NSBundle *bd = BALocalizedBundle();
UIImage *icon = nil;
if (bd){
icon = [UIImage imageNamed:imageName inBundle:bd withConfiguration:config];
}
if (!icon) {
icon = [UIImage imageNamed:imageName inBundle:nil withConfiguration:config];
}
return icon;
}
else{
//iOS 17.0之前,动态加载本地化图片,需要放在非Assets中。
NSString *imagePath = BALocalizedFile([NSString stringWithFormat:@"%@%@", imageName, @"@3x"], @"png");
if (!imagePath || imagePath.length == 0) {
//从Main bundle中加载Assets下的图片资源。
return [UIImage imageNamed:imageName];
}
else{
return [UIImage imageWithContentsOfFile:imagePath];
}
}
}
注意:加载“图片”资源的实现,在iOS17以后已有对应实现。iOS17之前,要想图片根据App设置语言加载,需要将图片资源放在非XCode创建的“Assets”文件夹下,才可以实现加载。图片默认支持@3x的png文件,这里可根据自己的情况进行修改。
简单使用:
1:找到“项目名称-Prefix.pch”,加入#import "BALocalized.h"
2:在Appdelegate中的didFinishLaunchingWithOptions中调用:BALocalizedInitLanguage(BALocalizedReadLanguage());
3:本地化文字,调用:BALocalizedString(key, table),table根据情况可设置为nil。
4:本地化图片,调用:BALocalizedImage(imageName)
5:本地化plist,调用:BALocalizedPlist(fileName)
6:在App设置语言界面中,选中某个语言后,调用:
(1)BALocalizedSaveLanguage(@"en"); //“en"为当前选择的语言名称。
(2)BALocalizedInitLanguage(BALocalizedReadLanguage());
(3)刷新界面(如重设window.rootViewController )。
觉得帮助到你了,记得点赞喔!
网友评论