现在我知道苹果不推荐这样做。
通常,您不应在应用程序内更改iOS系统语言(通过使用AppleLanguages首选项键)。这违反了在设置应用程序中切换语言的基本iOS用户模型,并且还使用了未记录的首选项键,这意味着将来某个时候,键名可能会更改,这会破坏您的应用程序。
但是,这是一个可以随时更改语言的应用程序,请相信我。我也知道有人问过这个问题:在运行iOS时以编程方式实时更改语言。但是,这种方法已经过时了,我想知道是否有更新,更好或更容易的方法来做到这一点。当前在我的应用中,我有一个语言选择屏幕。单击此视图中的按钮会调用该按钮所关联的语言的以下功能:
func changeLang(language: String) {
if language != (currentLang as! String?)! {
func handleCancel(alertView: UIAlertAction!)
{
}
var alert = UIAlertController(title: NSLocalizedString("language", comment: "Language"), message: NSLocalizedString("languageWarning", comment: "Warn User of Language Change Different Than Defaults"), preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler:handleCancel))
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default, handler:{ (UIAlertAction) in
NSUserDefaults.standardUserDefaults().setObject([language], forKey: "AppleLanguages")
NSUserDefaults.standardUserDefaults().synchronize()
println(self.currentLang)
let alert = UIAlertView()
alert.title = NSLocalizedString("language", comment: "Sign In Failed")
alert.message = NSLocalizedString("languageChangeNotification", comment: "Notify of language change")
alert.addButtonWithTitle(NSLocalizedString("ok", comment: "Okay"))
alert.show()
self.performSegueWithIdentifier("welcome", sender: AnyObject?())
}))
self.presentViewController(alert, animated: true, completion: {
})
} else {
self.performSegueWithIdentifier("welcome", sender: AnyObject?())
}
}
例:
@IBAction func english(sender: UIButton) {
changeLang("en")
}
如果用户选择的语言不同于他们自己的语言,则会收到确认警报,然后要求重新启动该设备。这就是我要更改的内容。直到应用程序重新启动,NSUSerDefaults的这一部分才会同步。证据:
let currentLang: AnyObject? = NSLocale.preferredLanguages()[0]
println(currentLang)
// Prints english
changeLang("zh-Hans")
println(currentLang)
// Prints english still until restart
苹果当前拥有的国际化体系很棒,我计划使用它。但是,如何通过强制在NSUSerDefaults上进行更新来即时更改语言?
编辑: 我建议立即使用此库来执行此操作。祝你好运!
基本上,您必须教您捆绑软件如何通过加载不同的捆绑软件文件来切换语言。
我将我的Objective-C代码翻译为Swift-保持了NSBundle类别不变。
结果是提供了languageDidChange()
一种覆盖方法的视图控制器类。
NSBundle + Language.h
#import <Foundation/Foundation.h>
@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end
NSBundle + Language.m
#import "NSBundle+Language.h"
#import <objc/runtime.h>
static const char associatedLanguageBundle=0;
@interface PrivateBundle : NSBundle
@end
@implementation PrivateBundle
-(NSString*)localizedStringForKey:(NSString *)key
value:(NSString *)value
table:(NSString *)tableName
{
NSBundle* bundle=objc_getAssociatedObject(self, &associatedLanguageBundle);
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],[PrivateBundle class]);
});
objc_setAssociatedObject([NSBundle mainBundle], &associatedLanguageBundle, language ?
[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
AppDelegate.swift
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "languageWillChange:", name: "LANGUAGE_WILL_CHANGE", object: nil)
let targetLang = NSUserDefaults.standardUserDefaults().objectForKey("selectedLanguage") as? String
NSBundle.setLanguage((targetLang != nil) ? targetLang : "en")
return true
}
func languageWillChange(notification:NSNotification){
let targetLang = notification.object as! String
NSUserDefaults.standardUserDefaults().setObject(targetLang, forKey: "selectedLanguage")
NSBundle.setLanguage(targetLang)
NSNotificationCenter.defaultCenter().postNotificationName("LANGUAGE_DID_CHANGE", object: targetLang)
}
}
BaseViewController.swift
import UIKit
class BaseViewController: UIViewController {
@IBOutlet weak var englishButton: UIButton!
@IBOutlet weak var spanishButton: UIButton!
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "languageDidChangeNotification:", name: "LANGUAGE_DID_CHANGE", object: nil)
languageDidChange()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func switchLanguage(sender: UIButton) {
var localeString:String?
switch sender {
case englishButton: localeString = "en"
case spanishButton: localeString = "es"
default: localeString = nil
}
if localeString != nil {
NSNotificationCenter.defaultCenter().postNotificationName("LANGUAGE_WILL_CHANGE", object: localeString)
}
}
func languageDidChangeNotification(notification:NSNotification){
languageDidChange()
}
func languageDidChange(){
}
}
ViewController.swift
import UIKit
class ViewController: BaseViewController {
@IBOutlet weak var helloLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func languageDidChange() {
super.languageDidChange()
self.helloLabel.text = NSLocalizedString("Hello", comment: "")
}
}
除了使用BaseViewController的子类,您的视图控制器还可以发布“ LANGUAGE_WILL_CHANGE”并侦听“
LANGUAGE_DID_CHANGE”
我将整个项目推到了这里:InstantLanguageSwitchSwift
问题内容: 我们如何用快速编程语言定义以下内容: 空值 零 零 [NSNull null] 换句话说,这些目标c项中的每一个的快速等效项是多少。此外,还想知道是否存在针对非目标c类型(如结构和枚举)的任何特定用例。提前致谢。 问题答案: 关于等效项: 在Swift中没有等效功能。 在Swift中也称为 在Swift中没有等效功能 可以在Swift中作为NSNull()访问 注意:这些是我基于阅读和
问题内容: 我得到的值是123456,我想在快速编程中将此值转换为1,23,456。我怎样才能做到这一点 ? 问题答案: 这是一种印度风格的数字格式,其中100,000(写为1,00,000)是一个“ lakh” 。 针对iOS中的不同区域设置从CurrencyFormatter转换和简化Objective-C代码可得到: Swift 3更新:
问题内容: 我目前正在成功使用以下代码在Selenium Webdriver中使用代理。不幸的是,如果不重新启动整个浏览器,我似乎无法使其更改代理设置。我曾希望仅更新代理服务器设置(就像我将代理服务器设置为开始那样)会更改代理服务器,但似乎不起作用。在这个问题上的任何帮助将不胜感激。 问题答案: 这是一个有点老的问题。但是实际上有可能通过“ hacky way ” 动态地更改代理,我将在 Fire
Java 是一种高级的编程语言,它最初是由 Sun 公司开发并于 1995 年公开发布的。Java 可以在不同的平台上运行,例如:Windows,Mac OS 和不同版本的 Unix。本指南将让你对 Java 有一个彻底的认识与了解。
问题内容: 我有登录功能 此函数用于将变量保存到会话中, 但是当新请求检查用户是否登录时 然后返回总是“注销”,因为会话已更改。我使用Redis来存储会话,我认为这是Redis的错误,因为当我停止使用Redis时,可以,请帮帮我! 问题答案: 最好的处理方式是始终让Express处理它(如果可以的话)。 https://flaviocopes.com/express-sessions/(更新了会话
问题内容: 这里的简单问题。我有一个UIButton,currencySelector,并且我想以编程方式更改文本。这是我所拥有的: Xcode给我错误“期望的声明”。我在做什么错,如何更改按钮的文本? 问题答案: 在Swift 3、4、5中: 除此以外: 还必须为声明。