以编程方式更改为从右到左的 RTL



我正在开发一个支持两种语言的应用程序:英语和阿拉伯语。当用户将语言更改为阿拉伯语时,我需要我的应用使文本从右到左 (RTL(。

搜索了这个问题,我找到了关于支持 RTL 的答案。

我想以编程方式应用上述答案,因为我需要在应用程序运行时从 LTR 更改为 RTL。

在 Swift 4 中试试这个,

//FOR RIGHT TO LEFT
 UIView.appearance().semanticContentAttribute = .forceRightToLeft
//FOR LEFT TO RIGHT
 UIView.appearance().semanticContentAttribute = .forceLeftToRight

使用此行代码,它将在不关闭应用程序的情况下更改布局。从右到左

UIView.appearance().semanticContentAttribute = .forceRightToLeft

对于从左到右翻

UIView.appearance().semanticContentAttribute = .forceLeftToRight
如果您想更改文本

字段布局或文本更改,请使用此代码,因为我遇到了这个问题. 文本字段的文本不是长宁布局。 检查此代码以更改文本字段文本的布局

extension UITextField {
open override func awakeFromNib() {
        super.awakeFromNib()
        if UserDefaults.languageCode == "ar" {
            if textAlignment == .natural {
                self.textAlignment = .right
            }
        }
    }
}

我使用以下命令将我的应用程序更改为从右到左的 RTL:

self.transform = CGAffineTransformMakeScale(-1.0, 1.0)
这翻转

了视图,然后我像这样翻转了视图中的对象:

label.transform = CGAffineTransformMakeScale(-1.0, 1.0)
textField.transform = CGAffineTransformMakeScale(-1.0, 1.0)
image.transform = CGAffineTransformMakeScale(-1.0, 1.0)

这使我的观点成为 RTL,而不是更改所有约束或将应用程序重建为 RTL。

Swift 5 已弃用

UIView.appearance().semanticContentAttribute = .forceRightToLeft

改用这个

self.view.semanticContentAttribute = .forceRightToLeft

UIView.semanticContentAttribute折旧后更新。

03/05/2018 : 既然@SalmaGh已经回答了他自己的问题。
但是该解决方案会使您的UI/UX严重混乱。
我会就如何解决这个问题提出建议。

这个答案来自多个答案,应该被投赞成票而不是反对票。

原因:向应用添加语言切换器只会使其更加混乱

此解决方案是必需的,因为某些阿拉伯语语言(例如 @Afshin M. Khiabani 提到的(是在应用程序手动而不是库/框架/设备默认中完成的。 这使开发人员可以更好地控制其应用程序。 但是,此方法不是首选。

警告:这会用子视图弄乱 Horizantal 滚动视图

但是,如果您必须强制 LTL 视图为 RTL。 建议使用 IOSPercyJaydip 答案。 但请做一个标记进行检查。 例如let isArabic = false或使用的用户默认值。


首先在 AppDelegate didFinishLaunchingWithOptions
中输入代码 为什么我们要在 AppDelegate 中进行此检查是因为 AppDelegate 上的 UIView 将是所有视图控制器的超级视图。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
     self.ChangeLayout()
    return true
}
func ChangeLayout(){
    var languageCode = ""
    if let value = UserDefaults.standard.string(forKey: "Applanguage") {
        languageCode = value
    }else{
        languageCode = ""
    }
    if(languageCode == "ar"){
        UIView.appearance().semanticContentAttribute = .forceRightToLeft
    }else{
        UIView.appearance().semanticContentAttribute = .forceLeftToRight
    }
}

如果应用语言保存">ar",此代码将自动以 RTL 模式加载应用程序,但这只会在您重新打开应用程序时发生一次。


但是您可以通过调用 AppDelegate 函数来访问该函数,如下所示:

        let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
        appDelegate?.ChangeLayout()


然后调用 TopMost ViewController 例如 LoadScreen 或其他东西来使重新加载流程。

由于它是您自己的应用程序,因此我假设您可以控制它的 UI 元素。

如果是这样,您不仅可以提供满足您要求的NSLayoutConstraint,还可以指定文本和按钮表示形式的对齐方式:NSTextAlignment

由于无法以编程方式控制系统设置,因此请记住,您的应用将不再利用自然约束,例如leadingtrailing

当您

需要阿拉伯语布局时,请在方法 didFinishLaunchingWithOptions 中使用以下行,对于环球银行间金融电信协会

UIView.appearance((.semanticContentAttribute = .forceRightToLeft

对于目标C

[UIView appearance].semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;

并使用重新加载应用程序

[self application:app didFinishLaunchingWithOptions:nil];

在应用程序委托中的其他方法中。调用要更改应用语言的该方法。

反之亦然,用于应用程序的英语本地化。

Swift 5 with Scene Delegate

我创建了一个简单的单例类,它将使用 Localizable.string 文件动态切换语言,它还将替换 keyWindow 的 rootViewController 并充当 AppRestart,用于详细实现我写了一篇文章你可以在这里阅读

//
//  AppLanguage.swift
//  Created by Mohamad Kaakati on 30/05/2021.
//
import UIKit
enum Languages {
    case english, arabic, french
}
class AppLanguage {
    
    static let shared = AppLanguage()
    private init() { }
    
    var bundle: Bundle?
    
    func set(index: Languages) {
        switch index {
        case .english:
            // For English Language set LTR
            print("Set language to LTR")
            selectBundleForResource(forResource: "en", isRTL: false)
        case .arabic:
            // For RTL Language set RTL
            print("Set language to RTL.")
            selectBundleForResource(forResource: "ar", isRTL: true)
        default:
            // For French Language set LTR
            selectBundleForResource(forResource: "fr", isRTL: false)
        }
        
    }
    
    private func selectBundleForResource(forResource: String!, isRTL: Bool) {
        guard let path = Bundle.main.path(forResource: forResource, ofType: "lproj") else {
            return
        }
        self.bundle = Bundle.init(path: path)
        switchViewControllers(isRTL: isRTL)
    }
    
    private func setKeyWindowFromAppDelegate(isRTL: Bool) {
        UIView.appearance().semanticContentAttribute = isRTL ? .forceRightToLeft : .forceLeftToRight
        let appDelegate = UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate
        let homeViewController = UIViewController() // Replace with your root view controller.
        appDelegate?.window?.rootViewController = homeViewController
    }
    
    private func switchViewControllers(isRTL rtl : Bool){
        if rtl {
            setKeyWindowFromAppDelegate(isRTL: true)
        } else {
            setKeyWindowFromAppDelegate(isRTL: false)
        }
    }
}
public extension String {
    /// Return Localized String
    var localizedString : String {
        get {
            return self.toLocal()
        }
    }
}
private extension String {
    func toLocal() -> String {
        if AppLanguage.shared.bundle != nil {
            return NSLocalizedString(self, tableName: "Localizable", bundle: AppLanguage.shared.bundle!, value: "", comment: "")
        }
        return self
    }
}

您可以使用以下方法设置语言:

AppLanguage.shared.set(index: .arabic)

你介意我问你为什么需要这个吗?

我强烈建议在执行此操作之前三思而后行,主要是因为它提供了令人困惑的用户体验。用户希望他们的应用遵循系统语言,因此没有任何方法可以在应用内选择语言。

iOS 讓你很容易以正確的方式做;如果你使用 Auto Layout,在 UIKit API 上構建你的自訂控制,並使用 NSLocalizedString,一切都會在 Runtime 為你的用戶做正確的事情。

swift 5

在 NSA归属字符串上对齐和右对齐或左对齐

let paragraphStyle = NSMutableParagraphStyle()
     if(arabic){
              paragraphStyle.alignment = .justified
              paragraphStyle.baseWritingDirection = .rightToLeft
              
          }else{
              paragraphStyle.alignment = .justified
              paragraphStyle.baseWritingDirection = .leftToRight
          }

最新更新