当前位置: 首页 > 面试题库 >

如何在应用程序中设置本地化方向?(如果用户选择阿拉伯语,则选择RTL,选择LTR则选择语言为英语) 迅速

宫俊才
2023-03-14
问题内容

我的应用程序必须支持阿拉伯语(从右到左方向)和英语(从左到右方向)语言,我需要设置UI并基于用户
从我的应用程序中选择的语言。

我将使用NSLayoutConstraint实现UI,以便它可以根据前导和尾随约束自动更新UI 。

现在我的问题是我该如何实现?由于我的设备语言是英语,并且从我的应用程序用户中选择阿拉伯语(仅限于我的应用程序),因此我的Flow,UI,动画等应从右到左。


问题答案:

最重要的是,您可以在应用程序内部更改语言。但是,需要额外的
工作。我列出了每个iOS
版本的限制背景,然后提供了解决方案。因为在解释
解决方案时,您需要了解其背后的原因。

更新(iOS 9+)
解决方案密钥:semanticContentAttribute

有人说这种方式不是官方的,可能会导致效率问题。

现在可以在不关闭应用程序的情况下强制执行UI方向:

UIView.appearance().semanticContentAttribute = .forceRightToLeft

请注意,iOS 9中的条不能强制为RTL(导航和TabBar)。尽管它
在iOS 10中被强制使用。

iOS 10中唯一不能强制使用RTL的功能是默认的
后退按钮。

更改应用程序的语言以及强制布局不会
自动强制系统使用
与该语言关联的本地化字符串文件。

在iOS 9以下
简短答案:

更改应用程序语言将不会在
不重新启动应用程序的情况下根据所选语言强制布局方向。

苹果的指导方针:

苹果公司不提供这种服务,因为他们不喜欢允许用户
从应用程序内部更改语言。苹果公司要求开发人员使用
设备语言。而不是完全从应用程序内部进行更改。

工作伤口:

某些支持阿拉伯语言的应用程序会在设置页面
(该页面中用户可以更改语言)中向用户提示,如果不
重新启动应用程序,布局将不会生效。存储示例
应用程序的链接

将应用程序语言更改为阿拉伯语的示例代码:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"ar", @"en", nil] forKey:@"AppleLanguages"];

That won’t take effect without a restart

Solution is to provide your own localization solution:

  1. Use Base Internationalization but don’t localize storyboards.
  2. Create one strings file and localise it to all languages and base for (english).
  3. Place the change language feature in a ViewController that starts before any other ViewController even before your main one. OR use an unwindSegue to go back to the root view controller after changing the language.
  4. Set strings for your views in viewDidLoad method for all view controllers.

Don’t satisfy points 5 and 6 if you are not supporting below iOS 9

  1. Set the constraints for your views in viewDidLoad method for all view controllers.

  2. When you set the constraints use right/left according to the language selected instead of leading/trailing.

Language class sample (Swift): Initialise an object of this class in your
singlton class.

class LanguageDetails: NSObject {

    var language: String!
    var bundle: Bundle!
    let LANGUAGE_KEY: String = "LANGUAGE_KEY"

    override init() {
        super.init()

        // user preferred languages. this is the default app language(device language - first launch app language)!
        language = Bundle.main.preferredLocalizations[0]

        // the language stored in UserDefaults have the priority over the device language.
        language = Common.valueForKey(key: LANGUAGE_KEY, default_value: language as AnyObject) as! String

        // init the bundle object that contains the localization files based on language
        bundle = Bundle(path: Bundle.main.path(forResource: language == "ar" ? language : "Base", ofType: "lproj")!)

        // bars direction
        if isArabic() {
            UIView.appearance().semanticContentAttribute = .forceRightToLeft
        } else {
            UIView.appearance().semanticContentAttribute = .forceLeftToRight
        }
    }

    // check if current language is arabic
    func isArabic () -> Bool {
        return language == "ar"
    }

    // returns app language direction.
    func rtl () -> Bool {
        return Locale.characterDirection(forLanguage: language) == Locale.LanguageDirection.rightToLeft
    }

    // switches language. if its ar change it to en and vise-versa
    func changeLanguage()
    {
        var changeTo: String
        // check current language to switch to the other.
        if language == "ar" {
            changeTo = "en"
        } else {
            changeTo = "ar"
        }

        // change language
        changeLanguageTo(lang: changeTo)

        Log.info("Language changed to: \(language)")
    }

    // change language to a specfic one.
    func changeLanguageTo(lang: String) {
        language = lang

        // set language to user defaults
        Common.setValue(value: language as AnyObject, key: LANGUAGE_KEY)

        // set prefered languages for the app.
        UserDefaults.standard.set([lang], forKey: "AppleLanguages")
        UserDefaults.standard.synchronize()

        // re-set the bundle object based on the new langauge
        bundle = Bundle(path: Bundle.main.path(forResource: language == "ar" ? language : "Base", ofType: "lproj")!)

        // app direction
        if isArabic() {
            UIView.appearance().semanticContentAttribute = .forceRightToLeft
        } else {
            UIView.appearance().semanticContentAttribute = .forceLeftToRight
        }

        Log.info("Language changed to: \(language)")
    }

    // get local string
    func getLocale() -> NSLocale {
        if rtl() {
            return NSLocale(localeIdentifier: "ar_JO")
        } else {
            return NSLocale(localeIdentifier: "en_US")
        }
    }

    // get localized string based on app langauge.
    func LocalString(key: String) -> String {
        let localizedString: String? = NSLocalizedString(key, bundle: bundle, value: key, comment: "")
//        Log.ver("Localized string '\(localizedString ?? "not found")' for key '\(key)'")
        return localizedString ?? key
    }

    // get localized string for specific language
    func LocalString(key: String, lan: String) -> String {
        let bundl:Bundle! = Bundle(path: Bundle.main.path(forResource: lan == "ar" ? lan : "Base", ofType: "lproj")!)
        return NSLocalizedString(key, bundle: bundl, value: key, comment: "")
    }
}

Language class sample (Objective-c): Swift sample provides full solution.
sorry you need to convert it yourself.

@implementation LanguageDetails

@synthesize language;
@synthesize bundle;

#define LANGUAGE_KEY @"LANGUAGE_KEY"

// language var is also the strings file name ar or en

- (id)init
{
    if (self = [super init]) {

        language = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0];

        if (![language isEqualToString:@"ar"])
            language = @"en";

        language = [Common valueForKey:LANGUAGE_KEY defaultValue:language];

        bundle = [NSBundle mainBundle];
    }
    return  self;
}

- (BOOL)rtl {
    return [NSLocale characterDirectionForLanguage:language] == NSLocaleLanguageDirectionRightToLeft;
}

- (void)changeLanguage
{
    if ([language isEqualToString:@"ar"])
        language = @"en";
    else
        language = @"ar";

    [Common setValue:language forKey:LANGUAGE_KEY];
}

- (void)changeLanguageTo:(NSString *)lang
{
    language = lang;

    [Common setValue:language forKey:LANGUAGE_KEY];
}

- (NSString *) LocalString:(NSString *)key {
    return NSLocalizedStringFromTableInBundle(key, language, bundle, nil);
}

@end


 类似资料:
  • 喜欢程序员这份工作的独立的程序员可以为任务选择最好的语言。大多数职业程序员控制不了他们将要使用的语言。通常,这个话题会由执行行政决议而非技术决议的boss说出,他们缺少勇气去提升新型工具,即使他们知道,大多数时候使用最新的知识,最少被接受的工具是最好的。另一些情况下,这种团体中真实的好处,以及拓展一个更大的社区的好处,排除了个人的选择。通常管理者由能够雇用在给定的语言有些经验的程序员驱动。毫无疑问

  • 如何选择shell编程语言 熟悉 vs 陌生 如果你已经掌握了一门编程语言(如PHP、Python、Java、JavaScript),建议你就直接使用这门语言编写脚本程序,虽然某些地方会有点啰嗦,但你能利用在这门语言领域里的经验(单元测试、单步调试、IDE、第三方类库)。 新增的学习成本很小,只要学会怎么使用shell解释器(Jshell、AdaScript)就可以了。 简单 vs 高级 如果你觉

  • 我有两个下拉列表,我想在它们被选中后使用它们。我想在选择的基础上弹出另一个框来显示信息。当我尝试使用if语句并按下ok按钮时,它只是继续到下一行。我从一个showMessage对话框开始,但我想在一些下拉选项中显示警告。它不起作用。我还需要能够循环返回主菜单,以便他们可以做出不同的选择。 我现在拥有的例子:

  • 我希望我的应用程序支持三种语言西班牙语,葡萄牙语 1)3个可绘制文件夹可绘制-es,可绘制-pt,可绘制。 2)3个值文件夹值-es,值-pt,值。根据语言更改String.xml值。 我有imageView来选择语言。当点击它时,菜单打开,包括选项英语、西班牙语、葡萄牙语。 我通过以下代码在选项选择上设置应用程序内部的区域设置 我已在清单中声明-android:configChanges=“lo

  • Why do developers choose one programming language over another for a given task? 为什么对一项给定的任务,开发者会偏向于选择某一门语言? Sometimes I choose raw C when I need blazing speed. 有时候当我需要绝对程序运行效率的时候,我会选择原始C语言。 When I wa

  • 问题内容: 我想设置一个先前选择的要在页面加载时显示的选项。我用以下代码尝试了它: 与 但这是行不通的。有任何想法吗? 问题答案: 这绝对应该工作。确保已将代码放入: