我知道很多帖子说这不应该做,或者是不可能的。我修补了一些想法,现在我问这个问题,因为我想绝对确定没有其他选择。
选项1:
最流行的解决方案是像this post那样修改AppleLanguages
。我不介意需要重启的想法,所以这对我来说是一个可以接受的解决方案,除了你不能以编程方式重启你的应用程序(找不到方法,否则会被苹果拒绝)。要求用户手动重启应用程序并不理想。
选项2:
下一个解决方案是获得适当的包,并对每个UILabel
、UIButton
等执行localizedStringForKey
查找。这可能有点乏味,但对我来说没问题,因为我已经将localizationProperties(类似于this)添加到这些视图中,这样我就可以有一个集中的字符串文件。
AppDelegate.swift:
static var userLanguage: String?
{
set
{
let defaults = NSUserDefaults.standardUserDefaults();
defaults.setObject(newValue, forKey: LanguageKey);
defaults.synchronize();
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle());
instance.window?.rootViewController = storyboard.instantiateInitialViewController();
}
get
{
let defaults = NSUserDefaults.standardUserDefaults();
return defaults.stringForKey(LanguageKey);
}
}
Localization.swift:
private var bundle: NSBundle
{
get
{
let bundle: NSBundle;
#if TARGET_INTERFACE_BUILDER
bundle = NSBundle(forClass: self.dynamicType);
#else
bundle = NSBundle.mainBundle();
#endif
let lang: String;
if(AppDelegate.userLanguage == nil || AppDelegate.userLanguage == "en")
{
lang = "Base";
}
else
{
lang = AppDelegate.userLanguage!;
}
let path = bundle.pathForResource(lang, ofType: "lproj");
if(path != nil)
{
let toreturn = NSBundle(path: path!);
if(toreturn != nil)
{
return toreturn!;
}
}
return bundle;
}
}
extension UILabel
{
@IBInspectable var localizedText: String?
{
get { return "" }
set
{
if(newValue != nil)
{
text = bundle.localizedStringForKey(newValue!, value:"", table: nil);
}
}
}
}
选项2的问题是,它只为那些字段设置语言。布局方向将保持不变,并且不会使用诸如语言特定布局之类的文件。
通过扩展UIApplication
,我能够指定一个自定义的userInterfaceLayoutDirection
,它成功地在LTR和RTL之间交换所有布局。
DemoApplication.swift:
class DemoApplication: UIApplication
{
override internal var userInterfaceLayoutDirection: UIUserInterfaceLayoutDirection
{
get
{
if(AppDelegate.userLanguage == "ar")
{
return UIUserInterfaceLayoutDirection.RightToLeft;
}
return UIUserInterfaceLayoutDirection.LeftToRight;
}
}
}
现在,当我设置AppDelegate.userLanguage
时,应用程序将重置为初始视图控制器,显示新的语言,在LTR和RTL之间翻转布局。这 * 没有 * 解决语言特定文件的问题,而且我还注意到文本在其自己的边界内保持左对齐或右对齐。
因为我找不到原生iOS类的源代码,所以我看不到启动时设置了哪些语言特定的变量,所以我假设它链接到NSBundle.mainBundle
。我试图使用swizzling方法覆盖它。
extension NSBundle
{
override public class func initialize()
{
struct Static
{
static var token: dispatch_once_t = 0;
}
// make sure this isn't a subclass
if (self !== NSBundle.self)
{
return;
}
dispatch_once(&Static.token)
{
do
{
try jr_swizzleClassMethod("mainBundle", withClassMethod: "mainBundleExt");
}
catch
{
print("\(error)");
}
}
super.initialize();
}
public class func mainBundleExt() -> NSBundle
{
let bundle = self.mainBundleExt(); // Due to swizzling, this is the "super" method
let lang: String;
if(AppDelegate.userLanguage == nil || AppDelegate.userLanguage == "en")
{
lang = "Base";
}
else
{
lang = AppDelegate.userLanguage!;
}
let path = bundle.pathForResource(lang, ofType: "lproj");
if(path != nil)
{
let toreturn = NSBundle(path: path!);
if(toreturn != nil)
{
return toreturn!;
}
}
}
}
但这并不起作用,似乎仍在使用默认的mainBundle
。
所以我的问题是:mainBundle
是如何赋值的?还有哪些特定于语言的变量是在启动时设置的,比如userInterfaceLayoutDirection
。我假设有2个或3个这样的变量。最后,这有可能工作吗?或者我只是在浪费时间?
- 谢谢-谢谢
2条答案
按热度按时间toe950271#
我以前遇到过这个问题,我用过一个库。它帮助我在飞行中改变语言。尝试使用这个:https://github.com/Decybel07/L10n-swift
在运行时,可以通过设置language属性随时切换语言
y3bcpkx12#
使用这行代码,它将在不关闭应用程序的情况下更改布局。
对于从左向右翻转
如果你想改变文本字段布局或文本改变然后使用这个代码,因为我面临这个问题.文本字段的文本是不是改变布局.检查这个代码来改变文本字段文本的布局