Выравнивание текста SwiftUI

90

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

Есть ли какая-то концепция, которую мне не хватает в системе макета, SwiftUIи если нет, как я могу установить свойства выравнивания текста на Text?

иноки
источник

Ответы:

144

Сделать это можно с помощью модификатора .multilineTextAlignment(.center).

Документация Apple

vrwim
источник
8
Есть ли что-то для выравнивания текста?
theMouk
85

Начиная с версии SwiftUI beta 3, вы можете центрировать текстовое представление с помощью модификатора кадра:

Text("Centered")
    .frame(maxWidth: .infinity, alignment: .center)
Джим Марквардт
источник
39

Пытался понять это сам, поскольку здесь упоминаются другие ответы 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))

образ

staticVoidMan
источник
1
Это очень убедительный ответ. Спасибо. Я также рассмотрю вопрос о том, чтобы сделать этот ответ принятым.
inokey
1
@inokey рад поделиться своими наблюдениями :) Позже я нашел интересную статью, в которой более подробно рассказывается о
staticVoidMan
классный человек. SwiftUI действительно развился с тех пор, как я изначально разместил этот вопрос.
inokey
17

Я действительно столкнулся с проблемой, когда мне пришлось выровнять текст в одной строке. Я обнаружил, что работает следующее:

Text("some text")
    .frame(alignment: .leading)

Если вы объедините это с параметром ширины рамки, вы можете получить хорошее форматирование текстового блока для меток и тому подобного.

Лекяира
источник
14

Я думаю, что SwiftUIхочет, чтобы мы использовали обертки как стеки для таких вещей.

Поэтому вместо того, чтобы писать что-то вроде Text("Hello World").aligned(.leading), рекомендуется следующее:

VStack(alignment: .leading) {
    Text("Hello World")
}
Фредпи
источник
1
Значит, я не могу просто отбросить метку, независимую от стека?
inokey
@inokey По крайней мере, я не нашел для этого модификатора.
fredpi 04
Я тоже. Мне кажется, я скучаю по какой-то базовой концепции от SUI. Я даже не могу отбросить просто «вид» между двумя вещами и дать ему цвет, как будто там нет простого объекта a-la-uiview.
inokey
У модификатора кадра есть параметр выравнивания
EmilioPelaez
Это кажется глупым (хотя это работает). Где вы узнали, что это поощрялось?
MobileMon
6

Если вы хотите сохранить постоянную ширину для текста, ".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)
Камил Заборовски
источник
5

Нам нужно выровнять текст, а не стек, в котором он находится. Таким образом, вызывая multilineTextAlignment(.center)и устанавливая пределы строк, я могу видеть тексты, выровненные по центру. Я не знаю, зачем мне устанавливать границы строк, я думал, что это расширится, если у вас будет большой текст.

Text("blahblah")
        .font(.headline)
        .multilineTextAlignment(.center)
        .lineLimit(50)
Мики
источник
4

Вы можете установить выравнивание для Vertical stackView как ведущее. Как показано ниже

 VStack(alignment: .leading) {
            Text("Turtle Rock")
                .font(.title)
            Text("Joshua Tree National Park")
                .font(.subheadline)
        }

введите описание изображения здесь

Катиресан Муруган
источник
0

Я хочу использовать режим Spacer () для выравнивания текстового блока. В этом примере показан текст на задней стороне:

                HStack{
                    Spacer()
                    Text("Wishlist")
                }
Алексей Радецкий
источник