dahiya_boy
dahiya_boy

Reputation: 9503

semanticContentAttribute is not working

In my app there is three languages i.e. ar , fr & en. And Based on the app language is changing the app language and semantics.

In my app, app language is properly changed as per the requirement but its semantics is not changing.

Here is the tried code what I am doing when user changed the language.

let cur_lang = Localize.currentLanguage()
    print("current lang; \(cur_lang)")
    if cur_lang == "ar"{
        UIView.appearance().semanticContentAttribute = .forceRightToLeft
    }
    else{
        UIView.appearance().semanticContentAttribute = .forceLeftToRight
    }

    imgView.image = UIImage(named: "flag".localized())
    lblTitle.text = "Title".localized()
    lblDescription.text = "Description".localized()
    lblName.text = "Name".localized()
    tfName.text = "textName".localized()

Here is the gif of the screen.

enter image description here

Required Output:

enter image description here

Edit

If I take all contents in a view , then it is working as expected but natural text alignment and navigation bar is still uneffected.

It is not possible to flip each and every view as it may reduce app performance if there is complex layout.

So I tried self.view.semanticContentAttribute = .forceRightToLeft and it does not make any difference.

My every UI component have leading trailing not left right and respect language direction is also selected.

enter image description here

Upvotes: 10

Views: 11659

Answers (5)

Rajesh Mani
Rajesh Mani

Reputation: 51

Another way to solve this problem is put your condition code in

override func viewWillLayoutSubviews() {
        if Language.language == .arabic {
            DispatchQueue.main.async {
                self.inputTextField.semanticContentAttribute = .forceRightToLeft
                self.inputTextField.textAlignment = .right
            }

        } else {
            DispatchQueue.main.async {
                self.inputTextField.semanticContentAttribute = .forceRightToLeft
                self.inputTextField.textAlignment = .left
            }
        }
    }

Simply work ;)

Upvotes: 4

Rashid Latif
Rashid Latif

Reputation: 2901

Swift 4.2, 5.0

        if isArabic {
            UIView.appearance().semanticContentAttribute = .forceRightToLeft
            UIButton.appearance().semanticContentAttribute = .forceRightToLeft
            UITextView.appearance().semanticContentAttribute = .forceRightToLeft
            UITextField.appearance().semanticContentAttribute = .forceRightToLeft
        } else {
            UIView.appearance().semanticContentAttribute = .forceLeftToRight
            UIButton.appearance().semanticContentAttribute = .forceLeftToRight
            UITextView.appearance().semanticContentAttribute = .forceLeftToRight
            UITextField.appearance().semanticContentAttribute = .forceLeftToRight
        }

Upvotes: 7

Zaim Ramlan
Zaim Ramlan

Reputation: 591

  1. First step, you need to apply the semantic content attribute as mentioned in the other answers.

    // get current language using your 'Localize' class
    let locale = Localize.currentLanguage()
    UIView.appearance().semanticContentAttribute = locale == "ar" ? .forceRightToLeft : .forceLeftToRight
    

    However, this alone would not work because based on Apple's Doc:

    iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back.

  2. The second step is in the doc itself. You only need to remove the view from the view hierarchy and then put it back.

    let window = self.view.superview
    self.view.removeFromSuperview()
    window?.addSubview(self.view)
    

    Note: Since self.view is already instantiated and you're only removing it from the view hierarchy and putting it back, you don't need to worry about recreating the view from scratch. :)

Voila!

Upvotes: 9

MOHAMED REBIN K
MOHAMED REBIN K

Reputation: 1

for textFields - use can use extension like this:

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

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100533

Semantic content attribute must be applied to the direct parent of the view you want to flip when change the language , so do this for the parent view of flag imageV and the 2 labels

self.directParentView.semanticContentAttribute = .forceRightToLeft

Upvotes: 1

Related Questions