Вариант 1:
Самое популярное решение — изменить AppleLanguages, как в этом посте. Я не возражаю против необходимости перезагрузки, поэтому для меня это было бы приемлемым решением, за исключением того, что вы не можете перезапустить свое приложение программно (не можете найти метод или будет отклонено Apple). Просить пользователя перезапустить приложение вручную было бы не лучшим решением.
Вариант 2:
Следующее решение — получить соответствующий пакет и выполнить поиск localizedStringForKey для каждого UILabel, UIButton и т. д. Это может быть немного утомительно, но меня это устраивает, поскольку я уже добавил localizationProperties (аналогично этому) к этим представлениям, чтобы у меня был централизованный файл строк.
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);
}
}
Код: Выделить всё
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);
}
}
}
}
Расширяя 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;
}
}
}
Поскольку я не могу найти исходный код для собственных классов 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 присваивается значение? Какие другие переменные, специфичные для языка, устанавливаются при запуске, например userInterfaceLayoutDirection.
Я предполагаю, что таких переменных 2 или 3. Наконец, возможно ли, чтобы это сработало или я просто зря трачу время?
Спасибо.
Подробнее здесь: https://stackoverflow.com/questions/333 ... restarting
Мобильная версия