Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 设置“;“应用语言”;不';不要改变应用程序语言_Ios_Swift_Ios8 - Fatal编程技术网

Ios 设置“;“应用语言”;不';不要改变应用程序语言

Ios 设置“;“应用语言”;不';不要改变应用程序语言,ios,swift,ios8,Ios,Swift,Ios8,我正在尝试实现一个可以改变应用程序语言的功能。 我试着这样设置: let defaults = NSUserDefaults.standardUserDefaults() defaults.setObject("de", forKey: "AppleLanguages") 应用程序重启后,语言仍然是“系统默认值”。 现在我通过设置Scheme>Application Language>Language来测试不同的语言 但用户是否可以单击按钮并在重新启动后查看所选语言? 另外,什么是避免重新启动

我正在尝试实现一个可以改变应用程序语言的功能。
我试着这样设置:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("de", forKey: "AppleLanguages")
应用程序重启后,语言仍然是“系统默认值”。
现在我通过设置
Scheme>Application Language>Language

来测试不同的语言 但用户是否可以单击按钮并在重新启动后查看所选语言?


另外,什么是避免重新启动时更改语言的正确方法?

您可以在下面的AppDelegate.swift中尝试,但更改不会立即出现,而是在您停止并重新启动应用程序之后-

NSUserDefaults.standardUserDefaults().removeObjectForKey("AppleLanguages")
NSUserDefaults.standardUserDefaults().setObject(["de"], forKey: "AppleLanguages"   
NSUserDefaults.standardUserDefaults().synchronize()

是的,您可以立即更改应用程序语言,如

var language = "de"
let path = NSBundle.mainBundle().pathForResource(language, ofType: "lproj")
let bundle = NSBundle(path: path!)
let string = bundle?.localizedStringForKey("key", value: nil, table: nil)

将NSUserDefaults值用作语言。

如果出于测试目的,只需在模拟器设置应用程序中更改语言即可。
如果你想在你的应用程序中设置一种语言选择器,那么它很漂亮,我认为你不应该这样做。
您的应用程序从设备读取语言和区域设置,并相应地更改用户界面。
覆盖此行为非常困难,您永远无法完成语言的完全更改,例如,如果您尝试在应用程序中显示地图,并且您的设备语言为西班牙语,但应用程序语言为英语,您将看到用西班牙语书写的地图指示。

这是一个有帮助的项目。

以下是在
swift
-

假设我想强制
希伯来语
本地化:

1.创建自己的Main.swift类 2.删除您的AppDelegate.swift“主要”职责
/@UIApplicationMain您必须使用数组而不是字符串设置
AppleLanguages
键:

UserDefaults.standard.set(["de"], forKey: "AppleLanguages")

更新了@royherma的答案中提到的
main.Swift
文件的Swift语法。这将避免在覆盖UserDefaults设置后重新启动应用程序:

import Foundation
import UIKit

// Your initialization code here
let langCultureCode: String = "LANGUAGE_CODE"

UserDefaults.standard.set([langCultureCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()

UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))

与删除
AppDelegate.swift
文件中的
@UIApplicationMain
一起使用。

此解决方案对我有效:
1.创建捆绑包的扩展



    import Foundation

    class L012Localizer: NSObject {
        class func DoTheSwizzling() {
            MethodSwizzleGivenClassName(cls: Bundle.self, originalSelector: #selector(Bundle.localizedString(forKey:value:table:)), overrideSelector:
                #selector(Bundle.specialLocalizedString(key:value:table:)))
        }
    }

    extension Bundle {
        @objc func specialLocalizedString(key: String, value: String?, table tableName: String?) -> String {
            let currentLanguage = Utils.currentLanguage().rawValue
            var bundle = Bundle();
            if currentLanguage != "" , let _path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
                bundle = Bundle(path: _path)!
            } else {
                let _path = Bundle.main.path(forResource: "Base", ofType: "lproj")!
                bundle = Bundle(path: _path)!
            }
            return (bundle.specialLocalizedString(key: key, value: value, table: tableName))
        }
    }

    func MethodSwizzleGivenClassName(cls: AnyClass, originalSelector: Selector, overrideSelector: Selector){

        let origMethod: Method = class_getInstanceMethod(cls, originalSelector)!;
        let overrideMethod: Method = class_getInstanceMethod(cls, overrideSelector)!;
        if (class_addMethod(cls, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
            class_replaceMethod(cls, overrideSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        } else {
            method_exchangeImplementations(origMethod, overrideMethod);
        }
    }


2.在AppDelegate中调用DoTheSwizzling


3.创建语言UTIL


4.创建语言类型


5.请记住,您必须将方案中的应用程序语言配置为系统语言


6.然后每次你需要本地化你的应用程序,你只需要打电话Utils.setLanguage({LanguageType})

我尝试了这个应用程序内委托,但它没有改变任何东西。你检查过你的NSUserDefaults是否保存了你保存的值吗?很抱歉,你的代码工作正常,我不理解这一点。这意味着,当用户更改语言时,我必须以某种方式将其(语言代码)保存在userdefaults中,并在每次翻译时获得它,对吗?@Paddy。自从一周以来,我一直在改变语言,当我添加代码时,我怎么能以编程方式改变我的语言呢?我会在发送本地化推送通知时崩溃。但如果我决定采取强硬措施,那就意味着我需要按照@Paddy在回答中所写的方式,在每个视图中获得本地化值。我说得对吗?Paddy解释的方法强制系统在指定的项目语言目录中查找本地化字符串。这不是唯一的方法。如果你在谷歌上搜索,你会发现很多实验,即使它们在obj-c中,后面的概念仍然有效。我已经创建了Main.swift文件,然后我需要在哪个函数或函数名下编写你在回答的第一点提供的代码???@idedeveloper no function,这就是
Main.swift
文件的外观。遗憾的是,这对我已经不起作用了……还有人在swift 3 xcode 7+中遇到问题吗?首先是Main.swift不是Main.swift,第二,这对xcode 8不起作用。@Deyaelden您找到了替代方法吗?我目前只需要在我的应用程序中使用希伯来语本地化,甚至不需要英语,但我无法从一开始就执行它。如果我在app Delegate中使用“AppLanguages”键,我必须先关闭应用程序一次,然后执行本地化。不,它没有
synchronize()
根据苹果的文档,不建议再使用了:我怎样才能更改这种语言,更多的时间?没有任何函数,所以下次如何执行“main.swift”文件代码?
import Foundation
import UIKit

// Your initialization code here
let langCultureCode: String = "LANGUAGE_CODE"

UserDefaults.standard.set([langCultureCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()

UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))


    import Foundation

    class L012Localizer: NSObject {
        class func DoTheSwizzling() {
            MethodSwizzleGivenClassName(cls: Bundle.self, originalSelector: #selector(Bundle.localizedString(forKey:value:table:)), overrideSelector:
                #selector(Bundle.specialLocalizedString(key:value:table:)))
        }
    }

    extension Bundle {
        @objc func specialLocalizedString(key: String, value: String?, table tableName: String?) -> String {
            let currentLanguage = Utils.currentLanguage().rawValue
            var bundle = Bundle();
            if currentLanguage != "" , let _path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
                bundle = Bundle(path: _path)!
            } else {
                let _path = Bundle.main.path(forResource: "Base", ofType: "lproj")!
                bundle = Bundle(path: _path)!
            }
            return (bundle.specialLocalizedString(key: key, value: value, table: tableName))
        }
    }

    func MethodSwizzleGivenClassName(cls: AnyClass, originalSelector: Selector, overrideSelector: Selector){

        let origMethod: Method = class_getInstanceMethod(cls, originalSelector)!;
        let overrideMethod: Method = class_getInstanceMethod(cls, overrideSelector)!;
        if (class_addMethod(cls, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
            class_replaceMethod(cls, overrideSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        } else {
            method_exchangeImplementations(origMethod, overrideMethod);
        }
    }




     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            L012Localizer.DoTheSwizzling()
            return true
        }



    class Utils: NSObject {
        class func setLanguage(_ lang: LanguageType) {
            UserDefaults.standard.set([lang.rawValue], forKey: "AppleLanguages")
        }

        class func currentLanguage() -> LanguageType {
            if let langs = UserDefaults.standard.object(forKey: "AppleLanguages") as? [String], let currentLang = langs.first {
                return LanguageType(rawValue: currentLang) ?? .english
            }

            return .english
        }
    }



    enum LanguageType: String {
        case english = "en"
        case korea = "ko"
        case vietnamese = "vi-VN"

        func toString() -> String {
            switch self {
            case .korea:
                return "Korea".localized
            case .vietnamese:
                return "Vietnamese".localized
            default:
                return "English".localized
            }
        }
    }