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

时间:2016-02-02 10:34:49

标签: ios iphone swift right-to-left

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

我搜索了这个问题,发现this answer关于支持RTL。

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

11 个答案:

答案 0 :(得分:7)

我使用以下方法将我的应用程序更改为从右到左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。

答案 1 :(得分:4)

使用此行代码,它将更改布局而无需关闭应用程序。从右到左

UIView.appearance().semanticContentAttribute = .forceRightToLeft

从左向右翻转

UIView.appearance().semanticContentAttribute = .forceLeftToRight

,如果您想更改文本字段布局或更改文本,请使用此代码,因为我遇到了这个问题。 textfield的文本未更改布局。检查此代码以更改文本字段文本的布局

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

答案 2 :(得分:2)

03/05/2018:因为@SalmaGh已回答他所拥有的问题。
但是这个解决方案会让你的UI / UX陷入困境 我会就如何解决这个问题提出建议。

这个答案是引用多个答案值得投赞而不是downvote。

  

原因:在您的应用中添加语言切换器只会让它更加混乱

此解决方案是必需的,因为某些阿拉伯语言(如 @Afshin M. Khiabani 提及)是在App Manually而非Library / Framework / Device Default中完成的。这使开发人员可以更好地控制他们的应用但是这种方法不适合。

警告:这会让Horizantal Scrollview陷入困境

但是如果必须强制LTL视图为RTL。建议使用 IOSPercy Jaydip 回答。但是请做一个标记检查。例如/\[TICKET(.*?)([0-9]+)/ 或使用用户默认值。


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

let isArabic = false

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


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

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
    }
}


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

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

当你想要阿拉伯语言布局时,在方法didFinishLaunchingWithOptions中使用以下行, 对于SWIFT

UIView.appearance()。semanticContentAttribute = .forceRightToLeft

对于目标C

[UIView外观] .semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;

并使用

重新加载应用
[self application:app didFinishLaunchingWithOptions:nil];

在appDelegate中的其他方法中。在您更改应用语言的地方调用该方法。

反之亦然,用于app的英文本地化。

答案 5 :(得分:0)

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

我强烈建议在此之前再考虑两次,主要是因为它提供了令人困惑的用户体验。用户希望他们的应用程序遵循系统语言,因此没有任何方法可以在应用程序中选择语言。

iOS使您可以非常轻松地以正确的方式执行此操作;如果您使用自动布局,在UIKit API上构建自定义控件并使用NSLocalizedString,一切都将在运行时为您的用户做正确的事。

答案 6 :(得分:0)

用于翻转UIView和UILabel的扩展解决方案

UIViews扩展
只要是View,它就可以与任何东西一起使用。

extension UIView{
   func flipView(){
       self.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
   }
}

像这样 *

  

这将翻转视图和该视图中的项目。

UIView.flipView()



UI标签扩展
我为UILabel做了一个单独的扩展,因为它与文本对齐有关

extension UILabel{
    func flipLabel(align: NSTextAlignment){
        self.textAlignment = align
        self.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
    }
}

像这样在UILabel上使用它

 UILabel.flipLabel(align: .right)

希望这可以帮助其他人更轻松地翻转视图。

答案 7 :(得分:0)

Swift 5已弃用

UIView.appearance().semanticContentAttribute = .forceRightToLeft

改为使用此

UIView.semanticContentAttribute = .forceRightToLeft

答案 8 :(得分:0)

迅速5

在NSAttributed字符串上对齐并左右对齐

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

答案 9 :(得分:0)

带有场景委托的 Swift 5

我创建了一个简单的单例类,它可以使用 Localizable.strings 文件即时切换语言,它还将替换 keyWindow 的 rootViewController 并充当 AppRestart,为了详细实现,我写了一篇文章 {{3} }

//
//  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)

答案 10 :(得分:-1)

//工作了

UIView.appearance().semanticContentAttribute = .forceRightToLeft

 
 UIView.appearance().semanticContentAttribute = .forceLeftToRight