Вирівнювання тексту SwiftUI


90

Серед багатьох властивостей Textподання я не зміг знайти жодного, пов’язаного з вирівнюванням тексту. У демонстраційній версії я бачив, що вона автоматично обробляє RTL, і, розміщуючи речі за допомогою View body, вона завжди центрирує їх автоматично.

Чи існує якась концепція, про яку мені не вистачає системи макетування, SwiftUIі якщо ні, то як я можу встановити властивості вирівнювання тексту на Text?

Відповіді:



85

З SwiftUI beta 3 вперед ви можете центрувати текстовий вигляд за допомогою модифікатора кадру:

Text("Centered")
    .frame(maxWidth: .infinity, alignment: .center)

40

Намагаюся зрозуміти це сам , як і інші відповіді тут згадати 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))

зображення


1
Це дуже вагома відповідь. Дякую. Я також подумаю зробити це прийнятою відповіддю.
inokey

1
@inokey радий поділитися своїми спостереженнями :) Пізніше я знайшов цікаву статтю, яка йде більш глибоко з вирівнюванням подання загалом: Посібники вирівнювання в SwiftUI
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 Я не знайшов модифікатора для цього принаймні.
фредпі

Я теж ні. Мені здається, що мені не вистачає якоїсь базової концепції від 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")
                }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.