SwiftUI Word Wrap для многострочного текста Проблема расстановки переносов в словах
Я столкнулся со следующей проблемой с SwiftUI Text: В следующем примере SwiftUI разбивает слово "Amazement" на "amazeme" в первой строке и "nt" во второй. Как этого избежать, не баг?
Я хочу, чтобы слово "изумление" было написано в одну строку. Есть ли какой-нибудь модификатор, позволяющий это (не разделять слова или что-то в этом роде)?
Пробовал.allowsTtening, .fixedSize. Изменен порядок модификаторов, не помогло.
Это ошибка или у нас пока нет возможности исправить это? Решение должно работать для каждой строки, а не только для указанной строки.
Вы можете воспроизвести поведение, используя этот код:
struct TestView2: View {
var body: some View {
ZStack {
Text("Amazement Awaits us at every corner")
.font(.system(size: 160))
.foregroundColor(.blue)
.foregroundColor(.white)
.lineLimit(4)
.multilineTextAlignment(.leading)
.minimumScaleFactor(0.01)
//.allowsTightening(true)
//.fixedSize(horizontal: false, vertical: true)
}
}
}
struct TestView2_Previews: PreviewProvider {
static var previews: some View {
TestView2()
}
}
3 ответа
Похоже, что перенос слов по символу используется по умолчанию, когда дело доходит до размещения текста в представлении. я нашел это
.minimumScaleFactor
работает только в том случае, если система не может вместить текст (с разрывами символов). Если это не сработало, он попытается уменьшить масштаб текста. Если попытаться уменьшить
linelimit
тогда
minimumScaleFactor
сработает и попытается уменьшить текст, пока он не уместится.
На данный момент я использую хак, где я проверяю количество символов слов в тексте, если в каком-либо слове больше символов, чем определенный порог, я уменьшаю размер шрифта, в противном случае я использую размер по умолчанию.
struct TestView2: View {
let text: String
var body: some View {
ZStack {
Text(self.text)
.font(.system(size: self.getSizeForText(self.text)))
.foregroundColor(.blue)
.foregroundColor(.white)
.lineLimit(4)
.multilineTextAlignment(.leading)
.minimumScaleFactor(0.01)
//.allowsTightening(true)
//.fixedSize(horizontal: false, vertical: true)
}
}
private fund getSizeForText(_ text: String) -> Double {
let CHARS_THRESHOLD = 12 // change this as needed
let words = text.split(separator: " ")
if words.contains(where: { $0.count > CHARS_THRESHOLD }) {
// text contains a long word, decrease the font size
return 150.0 // the smaller size, change as needed
}
// all words are shorter than the threshold
return 160.0 // the default size, change as needed
}
}
Это не будет работать для всех сценариев, но, надеюсь, это можно настроить, пока Apple не придумает правильное решение, поскольку я не могу представить сценарий, в котором разбиение слов по символам даже без дефиса является лучшим решением.
ИСПРАВЛЕНО: Xcode 13.3 / iOS 15.4
Text("Amazement Awaits us at every corner")
.font(.system(size: 460)) // << even such size (or any other big)
.foregroundColor(.blue)
.foregroundColor(.white)
.lineLimit(4)
.multilineTextAlignment(.leading)
.minimumScaleFactor(0.01)
Хотя я не нашел логической причины для исправления, но, похоже, вам нужно настроить
.lineLimit(3)
https:https://stackru.com/images/d1d91e39ff14643e641ba23242f603f65087e64e.jpg
Поиграйте со значениями lineLimit, которые вам больше всего подходят.