Среди множества свойств представления Text я не смог найти ни одного, связанного с выравниванием текста. Я видел в демонстрации, что он автоматически обрабатывает RTL, и при размещении материала с помощью body View он всегда автоматически центрирует его.
Есть ли какая-то концепция, которую я упускаю из системы макета в SwiftUI, и если нет, как я могу установить свойства выравнивания текста для Text?





Я предполагаю, что SwiftUI хочет, чтобы мы использовали обертки, такие как стеки, для таких вещей.
Поэтому вместо того, чтобы писать что-то вроде Text("Hello World").aligned(.leading), рекомендуется следующее:
VStack(alignment: .leading) {
Text("Hello World")
}
@inokey По крайней мере, я не нашел для этого модификатора.
Я тоже не знал. Мне кажется, что мне не хватает какой-то базовой концепции от SUI. Я даже не могу бросить просто «представление» между двумя вещами и придать ему цвет, как будто у них нет простого объекта a-la-uiview.
Модификатор фрейма имеет параметр выравнивания
Кажется глупым (хотя это работает). Откуда вы узнали, что это поощряется?
Сделать это можно с помощью модификатора .multilineTextAlignment(.center).
Существует ли что-то, чтобы оправдать текст?
Начиная с бета-версии SwiftUI 3, вы можете центрировать текстовое представление с помощью модификатора frame:
Text("Centered")
.frame(maxWidth: .infinity, alignment: .center)
Это лучшее решение!
Да, это должен быть ответ
По какой-то причине ".multilineTextAlignment()" не дал мне желаемых результатов, но это дало.
Это не работает в большинстве случаев
Нам нужно выровнять текст, а не стек, в котором он находится. Поэтому, вызвав multilineTextAlignment(.center) и установив ограничения строки, я смогу увидеть тексты, выровненные по центру. Я не знаю, почему я должен установить пределы строки, я думал, что это увеличится, если у вас большой текст.
Text("blahblah")
.font(.headline)
.multilineTextAlignment(.center)
.lineLimit(50)
На самом деле я столкнулся с проблемой, когда мне пришлось выровнять текст по одной строке. Что я нашел для работы, так это:
Text("some text")
.frame(alignment: .leading)
Если вы объедините это с параметром ширины рамки, вы можете получить красивое форматирование текстового блока для меток и тому подобного.
Если вы хотите сохранить постоянную ширину для текста, «.multilineTextAlignment(.leading)» не будет иметь никакого эффекта, пока не будет только одна строка текста.
Это решение, которое сработало для меня:
struct LeftAligned: ViewModifier {
func body(content: Content) -> some View {
HStack {
content
Spacer()
}
}
}
extension View {
func leftAligned() -> some View {
return self.modifier(LeftAligned())
}
}
Применение:
Text("Hello").leftAligned().frame(width: 300)
Сам пытался понять это, поскольку в других ответах здесь упоминаются Text.multilineTextAlignment(_:) / VStack(alignment:) / frame(width:alignment:), но каждое решение решает конкретную проблему. В конце концов, это зависит от требований пользовательского интерфейса и их комбинации.
VStack(alignment:)alignment здесь для внутренних взглядов по отношению друг к другу.
Таким образом, указание .leading свяжет все внутренние представления, чтобы их интерлиньяж был выровнен друг с другом.
VStack(alignment: .leading, spacing: 6) {
Text("Lorem ipsum dolor")
.background(Color.gray.opacity(0.2))
Text("sit amet")
.background(Color.gray.opacity(0.2))
}
.background(Color.gray.opacity(0.1))
.frameВ frame(width:alignment:) или frame(maxWidth:alignment:)alignment предназначен для содержимого в пределах заданной ширины.
VStack(alignment: .leading, spacing: 6) {
Text("Lorem ipsum dolor")
.background(Color.gray.opacity(0.2))
Text("sit amet")
.background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))
Внутренние представления выровнены по началу относительно друг друга, но сами представления выровнены по хвосту относительно VStack.
.multilineTextAlignmentЭто определяет выравнивание текста внутри и лучше всего видно, когда есть несколько строк, в противном случае без определенного frame(width:alignment) ширина настраивается автоматически и зависит от alignments по умолчанию.
VStack(alignment: .trailing, spacing: 6) {
Text("0. automatic frame\n+ view at parent's specified alignment\n+ multilineTA not set by default at leading")
.background(Color.gray.opacity(0.2))
Text("1. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to center")
.multilineTextAlignment(.center)
.background(Color.gray.opacity(0.2))
Text("2. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to trailing")
.multilineTextAlignment(.trailing)
.background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))
VStack(alignment: .trailing, spacing: 6) {
Text("1. automatic frame, at parent's alignment")
.background(Color.gray.opacity(0.2))
Text("2. given full width & leading alignment\n+ multilineTA at default leading")
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.gray.opacity(0.2))
Text("3. given full width & center alignment\n+ multilineTA at default leading")
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.gray.opacity(0.2))
Text("4. given full width & center alignment\n+ multilineTA set to center")
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.gray.opacity(0.2))
Text("5. given full width & center alignment\n+ multilineTA set to trailing")
.multilineTextAlignment(.trailing)
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.gray.opacity(0.2))
Text("6. given full width but no alignment\n+ multilineTA at default leading\n+ leading is based on content, looks odd sometimes as seen here")
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.2))
}
.frame(width: 380)
.background(Color.gray.opacity(0.1))
Это очень убедительный ответ. Спасибо. Я также рассмотрю возможность сделать это принятым ответом.
@inokey рад поделиться своими наблюдениями :) Позже я нашел интересную статью, в которой более подробно рассказывается о выравнивании представлений в целом: Руководства по выравниванию в SwiftUI
классная штука чувак. SwiftUI действительно развился с тех пор, как я впервые опубликовал этот вопрос.
Знаете ли вы, почему многострочный текст становится одной строкой, если я добавляю ex. Spacer().frame(height: 50) Если я уберу высоту из разделителя, в многострочном тексте будут отображаться все строки. Как принудительно показать все строки?
Я бы хотел использовать вид Spacer() для выравнивания текстового блока.
В этом примере показан текст на задней стороне:
HStack{
Spacer()
Text("Wishlist")
}
Не уверен, что это тот ответ, который вы ищете, но я обнаружил, что SwiftUI автоматически переключается на RTL для таких языков, как арабский, вам не нужно явно указывать это, как в UIKit.
У меня такая же проблема. я использовал это для исправления этого.
Text("Test")
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
Это дает очень странные результаты, я бы не рекомендовал
Вы всегда можете добавить рамку в текстовое поле и изменить его выравнивание.
Text("Hello World!")
.frame(alignment : .topLeading)
Так как это только для пары строк - это лучше, чем использовать выравнивание на любом из стеков.
То есть я не могу просто отбросить метку, независимую от стека?