SwiftUI - VStack делает дочерний текст на всю ширину

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

import SwiftUI

struct Test: View {
    @State private var text = "Hello, World!"

    var body: some View {
        VStack {
            Text(text)
                .frame(maxWidth: .infinity)
                .animation(.default)
            Button(action: {
                self.text = (self.text == "Text") ? "Hello, World!" : "Text"
            }) {
                Text("Toggle")
            }
        }
        .frame(maxWidth: .infinity)
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        Test()
    }
}

Когда я проверяю предварительный просмотр и наводю курсор на текст и стопку, он показывает именно то, что я ожидал, Textполная ширина. Однако когда я запускаю приложение и отлаживаю иерархию представлений, он показывает, чтоTextразмер рамки был изменен, чтобы соответствовать тексту. Хотя обычно я бы не возражал против этого, это приводит к анимации, показывающей эллипсы, когда текст изменяется на более длинную копию. Можно ли остановитьText от размера, чтобы соответствовать копии?

3 ответа

Вы можете попробовать другую анимацию, например spring:

            Text(text)
            .frame(maxWidth: .infinity)
            .animation(.spring(response: 0.0, dampingFraction:0.2))

Похоже, что ошибка трудно / невозможно исправить.

Вы можете использовать этот обходной путь, пока Apple не предоставит нам больше доступа к рамке и границам представления.

Использовать отключенный TextField вместо того Text:

TextField("", text: .constant(text))
    .multilineTextAlignment(.center)
    .disabled(true)
    .frame(maxWidth: .infinity)

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


Используйте отдельные объекты и переходите между ними:

Бонус: плавная анимация затухания.

struct ContentView: View {
    
    @State private var primaryText = "Hello, World!"
    @State private var alternativeText = "Text"
    @State private var isAlternative = false

    var body: some View {
        VStack {
            ZStack {
                Text(primaryText).opacity(isAlternative ? 0:1)
                Text(alternativeText).opacity(isAlternative ? 1:0)
            }.animation(.default)
            Button("Toggle") {
                self.isAlternative.toggle()
            }
        }
    }
}

Столкнулся с той же проблемой. Закончился довольно хакерским решением, но все же решает. Пожалуйста, закрой глаза. Добавление дополнительных пробелов решает проблему изменения размера.:)

Text(on ? "Cooling" : "Off         ")
Другие вопросы по тегам