带有TextKit和合理文本的iOS连字符

问题描述 投票:4回答:1

大家好。我在使用带有文本视图的TextKit时显示带连字符的正当文本有问题。我试图通过段落样式和NSLayoutManager进行断字,但是没有预期的结果。段落样式示例:

let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .justified
paragraph.lineBreakMode = .byWordWrapping
paragraph.hyphenationFactor = 0.85 //here goes the black magic :)

问题在于,合理的文本连字符看起来很糟糕,因为它会扩大字母(不是单词)之间的间隔。如果断字有效,一切看起来都很好。但这是另一个问题-连字号是根据当前电话首选语言的规则应用于文本的。这意味着,如果电话的首选语言是英语,并且文本是西里尔字母(例如俄语或乌克兰语),则根本不会使用连字号,并且会出现文本拉伸问题。这是这个问题的样子:

Stretched text without hyphenation

将电话的首选语言更改为文本语言会导致本机连字符很好地工作,并且正确显示正确的文本:

Nicely rendered text

因此,我的解决方案是使用NaturalLanguage框架确定文本语言,并将应用程序的首选语言更改为此语言。要确定文本语言,我使用以下代码段:

import NaturalLanguage

extension String {
    func dominantLanguage() -> Locale? {
        let languageRecognizer = NLLanguageRecognizer()
        languageRecognizer.processString(self)

        if let code = languageRecognizer.dominantLanguage?.rawValue {
            let language = Locale.init(identifier: code)
            return language
        } else if let code = languageRecognizer.languageHypotheses(withMaximum: 3).sorted(by: { (arg0, arg1) -> Bool in
            return arg0.value > arg1.value
            }).first?.key.rawValue {
            let language = Locale.init(identifier: code)
            return language
        } else {
            return nil
        }
    }
}

let locale = "qwerty".dominantLanguage()

但是此解决方案存在另一个问题:1)它不能100%正确地工作。例如,如果文本以表格开头(如上面的屏幕截图所示),则languageRecognizer.dominantLanguage返回nil,而languageHyphoteses可能返回错误的语言环境。我可能根本不依赖这个。2)每次更改应用程序的首选语言都是一种技巧。

我需要找到解决此问题的好方法,并且我想确保在不同的情况下不会发生任何故障。另外,我发现CoreText不适合我的其他目的,并且我发现TextKit对我来说很完美,但是我有这个问题,我不知道如何正确解决。

[此外,我发现使用WebView和CSS -webkit-hyphens可以很容易地进行断字(使用任何文本语言)和合理文本,但是我真的不想像CoreText一样投入使用WebView(确实不适合我的其他应用目的)。是否有任何想法如何使用TextKit实现该结果?我正在寻找可靠的解决方案。谢谢。

ios swift3 justify textkit hyphenation
1个回答
0
投票

使用UITextView代替UILabel是正确完成此工作的方法。

HyphenationFactor(作为NSParagraphStyle属性或NSLayoutManager属性)应能按预期工作。 -https://stackoverflow.com/a/19766990/6570914

© www.soinside.com 2019 - 2024. All rights reserved.