Как сделать вид между разделителями всегда в центре в HStack?

#ios #swift #swiftui

#iOS #swift #swiftui

Вопрос:

Чего я хотел бы достичь. независимо от ширины текста с обеих сторон, кнопка всегда должна находиться в центре HStack .

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

 HStack {
    Text("Foooooooo")
    Spacer(minLength: 5)
    Button(action: { }) {
        Text("Bar")
    }
    Spacer()
    Text("Baz")
}
.font(.system(size: 16, weight: .heavy, design: .rounded))
.padding()
  

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

Я также попытался использовать GeometryReader и установить размер кадра для каждого Text и Button в представлении, однако есть две проблемы,

  1. Просмотр, возвращаемый GeometryReader , будет занимать весь вид, который предлагает ему родительский элемент, вместо фактического внутреннего размера содержимого, места, достаточного только для Text , Spacer и Button
  2. Строка внутри первой Text не может быть выровнена по левому краю, поэтому строка внутри последней Text не может быть выровнена по правому краю

Ответ №1:

Вот возможный подход для вашего случая. Демо подготовлено и протестировано с Xcode 12 / iOS 14

ДЕМОНСТРАЦИЯ

     HStack {
        Spacer()
            .overlay(Text("Foooooooo"), alignment: .leading)

        Button(action: { }) {
            Text("Bar")
        }

        Spacer()
            .overlay(Text("Baz"), alignment: .trailing)
    }
    .font(.system(size: 16, weight: .heavy, design: .rounded))
    .padding()
  

Комментарии:

1. Наложение на разделитель, очень умный!

Ответ №2:

Вы хотите разместить три гибких элемента одинакового размера, но у вас есть три элемента фиксированного, но разного размера. Чтобы исправить это, поместите каждый элемент в свой собственный гибкий стек (HStack с разделителем), чтобы каждый занимал 1/3 пространства. Внутри каждого стека используйте разделители для выравнивания.

     HStack {
        // Left stack
        HStack {
            Text("Foooooooo")
            Spacer()
        }

        // Center stack. The surrounding Spacers aren't really required in this
        // specific case, but added for consistency and to show how to center.
        HStack {
            Spacer()
            Button(action: { }) {
                Text("Bar")
            }
            Spacer()
        }

        // Right stack
        HStack {
            Spacer()
            Text("Baz")
        }
    }
    .font(.system(size: 16, weight: .heavy, design: .rounded))
    .padding()
  

Ответ №3:

Вот еще один способ сделать это, который довольно лаконичен и использует ZStack для объединения кнопки по центру с HStack с помощью одного Spacer , чтобы сдвинуть метки к краям:

 ZStack {
    HStack {
        Text("Foooooooo")
        Spacer()
        Text("Baz")
    }
    Button(action: { }) {
        Text("Bar")
    }
}
.font(.system(size: 16, weight: .heavy, design: .rounded))
.padding()
  

Примечание: Это решение работает, если вы знаете, что ваши метки не будут затрагивать вашу кнопку. Решение @Asperi приводит к тому, что дополнительные длинные метки усекаются с помощью ... . Решение @RobNapier приводит к тому, что сверхдлинные метки переносятся на 1/3 ширины.