Всем добрый день. У меня проблема с отображением выровненного текста с дефисами, используя TextKit с текстовым представлением. Я пытался сделать перенос через стиль абзаца и NSLayoutManager, но без ожидаемых результатов. Пример стиля абзаца:
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .justified
paragraph.lineBreakMode = .byWordWrapping
paragraph.hyphenationFactor = 0.85 //here goes the black magic :)
Проблема в том, что выровненный текст без переносов выглядит ужасно, потому что растягивает пространство между буквами (а не словами). Все выглядит нормально, если расстановка переносов работает. Но вот еще одна проблема - перенос переносов применяется к тексту по правилам языка, предпочитаемого текущим телефоном. Это означает, что если предпочтительный язык телефона - английский, а текст - кириллица (например, русский или украинский язык), расстановка переносов вообще не применяется и возникает проблема с растянутым текстом. Вот как выглядит эта проблема:
Изменение предпочтительного языка телефона на язык текстов приводит к тому, что нативная расстановка переносов работает нормально, а выровненный текст также отображается правильно:
Итак, моим решением было определить язык текста и изменить предпочтительный язык приложений на этот с помощью фреймворка 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, но я действительно не хочу погружаться в работу с WebView, как и CoreText (не подходит для других целей моего приложения). Есть идеи, как добиться таких результатов с помощью TextKit? Ищу надежные решения. Спасибо.
dominantLanguage()
и предварительно обработать строку перед ее передачей вlanguageRecognizer.processString(PRE_PROCESSED_STRING)
. Есть несколько API, которые могут помочь вам, например, разбить строку на абзацы, и вы можете запускать функциюlanguageRecognizer.dominantLanguage?
для абзацев, пока не найдете правильное значение. Я почти уверен, что это решение повлияет на производительность, но оно поможет найти правильный доминирующий язык. - person dive   schedule 07.06.2020