Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect text direction based on content

Tags:

swift

I wonder if is it possible to set UITextView's text direction dynamically and based on its content?

Default behavior is like this: if you start a line with an LTR language that line will be LTR, but if you begin the next line with an RTL language that line's direction changes to RTL.

enter image description here

What I want is set entire paragraphs direction based on first one.

Is it possible?

like image 384
Maysam Avatar asked Mar 23 '16 10:03

Maysam


1 Answers

I've had this problem myself. With a little bit of search, made this extension for UITextView which detects the first letter's language and makes it RTL if it's needed. You need to call the function after setting text, so you may want to call it in UITextViewDelegate text change" method.

extension UITextView {
func detectRightToLeft() {
    if let text = self.text where !text.isEmpty {
        let tagschemes = NSArray(objects: NSLinguisticTagSchemeLanguage)
        let tagger = NSLinguisticTagger(tagSchemes: tagschemes as! [String], options: 0)
        tagger.string = text

        let language = tagger.tagAtIndex(0, scheme: NSLinguisticTagSchemeLanguage, tokenRange: nil, sentenceRange: nil)
        if language?.rangeOfString("he") != nil || language?.rangeOfString("ar") != nil || language?.rangeOfString("fa") != nil {
            self.text = text.stringByReplacingOccurrencesOfString("\n", withString: "\n")
            self.textAlignment = .Right
            self.makeTextWritingDirectionRightToLeft(nil)
        }else{
            self.textAlignment = .Left
            self.makeTextWritingDirectionLeftToRight(nil)
        }
    }
}
}

Surely this is messy and not perfect. But it worked for me. You can get the idea.

Swift 3:

extension UITextView {
    func detectRightToLeft() {
        if let text = self.text, !text.isEmpty {
            let tagschemes = NSArray(objects: NSLinguisticTagSchemeLanguage)
            let tagger = NSLinguisticTagger(tagSchemes: tagschemes as! [String], options: 0)
            tagger.string = text

            let language = tagger.tag(at: 0, scheme: NSLinguisticTagSchemeLanguage, tokenRange: nil, sentenceRange: nil)
            if language?.range(of: "he") != nil || language?.range(of: "ar") != nil || language?.range(of: "fa") != nil {
                self.text = text.replacingOccurrences(of: "\n", with: "\n")
                self.textAlignment = .right
                self.makeTextWritingDirectionRightToLeft(nil)
            }else{
                self.textAlignment = .left
                self.makeTextWritingDirectionLeftToRight(nil)
            }
        }
    }
}
like image 118
Arash R Avatar answered Oct 20 '22 14:10

Arash R