Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 361
dahiya_boy Avatar asked Mar 14 '18 12:03

dahiya_boy


4 Answers

  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!

like image 183
Zaim Ramlan Avatar answered Sep 20 '22 12:09

Zaim Ramlan


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
        }
like image 28
Rashid Latif Avatar answered Sep 16 '22 12:09

Rashid Latif


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

like image 20
Rajesh Mani Avatar answered Sep 18 '22 12:09

Rajesh Mani


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
like image 23
Sh_Khan Avatar answered Sep 18 '22 12:09

Sh_Khan