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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
196
0
151 764
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

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

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

VStack(alignment: .leading) {
    Text("Hello World")
}

То есть я не могу просто отбросить метку, независимую от стека?

inokey 04.06.2019 14:40

@inokey По крайней мере, я не нашел для этого модификатора.

fredpi 04.06.2019 15:13

Я тоже не знал. Мне кажется, что мне не хватает какой-то базовой концепции от SUI. Я даже не могу бросить просто «представление» между двумя вещами и придать ему цвет, как будто у них нет простого объекта a-la-uiview.

inokey 04.06.2019 15:16

Модификатор фрейма имеет параметр выравнивания

EmilioPelaez 12.06.2019 07:40

Кажется глупым (хотя это работает). Откуда вы узнали, что это поощряется?

MobileMon 31.07.2019 21:26

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

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

Ответ принят как подходящий

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

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

Существует ли что-то, чтобы оправдать текст?

theMouk 28.11.2019 11:20

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

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

Это лучшее решение!

Kushagra 06.05.2021 09:07

Да, это должен быть ответ

C0D3 11.10.2021 00:50

По какой-то причине ".multilineTextAlignment()" не дал мне желаемых результатов, но это дало.

Chad Mx 03.11.2021 06:47

Это не работает в большинстве случаев

Arturo 17.12.2021 05:49

Нам нужно выровнять текст, а не стек, в котором он находится. Поэтому, вызвав 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))

image


.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.

image


.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))

image


Тесты с комбинациями:

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))

image

Это очень убедительный ответ. Спасибо. Я также рассмотрю возможность сделать это принятым ответом.

inokey 16.05.2020 09:09

@inokey рад поделиться своими наблюдениями :) Позже я нашел интересную статью, в которой более подробно рассказывается о выравнивании представлений в целом: Руководства по выравниванию в SwiftUI

staticVoidMan 16.05.2020 09:19

классная штука чувак. SwiftUI действительно развился с тех пор, как я впервые опубликовал этот вопрос.

inokey 16.05.2020 09:36

Знаете ли вы, почему многострочный текст становится одной строкой, если я добавляю ex. Spacer().frame(height: 50) Если я уберу высоту из разделителя, в многострочном тексте будут отображаться все строки. Как принудительно показать все строки?

fullmoon 05.12.2021 16:16

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

HStack{
    Spacer()
    Text("Wishlist")
}

Не уверен, что это тот ответ, который вы ищете, но я обнаружил, что SwiftUI автоматически переключается на RTL для таких языков, как арабский, вам не нужно явно указывать это, как в UIKit.

У меня такая же проблема. я использовал это для исправления этого.

Text("Test")
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)

Это дает очень странные результаты, я бы не рекомендовал

Samuel Owino 14.12.2021 09:38

Вы всегда можете добавить рамку в текстовое поле и изменить его выравнивание.

Text("Hello World!")
   .frame(alignment : .topLeading)

Так как это только для пары строк - это лучше, чем использовать выравнивание на любом из стеков.

Другие вопросы по теме