Вопрос или проблема
Я использовал прозрачность как способ показать или скрыть элементы вида, не нарушая макет представлений. В этом примере я хочу, чтобы метка всегда оставалась по центру относительно горизонтали, независимо от того, показываются ли изображения info1 или info2.
import SwiftUI
struct ContentView: View {
@State var info1: Bool = false
@State var info2: Bool = false
@State var label: String = ""
var body: some View {
VStack {
TextField("Введите метку", text: $label)
.frame(width: 200)
Toggle("Информация 1", isOn: $info1)
.frame(width: 100)
Toggle("Информация 2", isOn: $info2)
.frame(width: 100)
HStack {
Image(systemName: "info.circle.fill")
.opacity(info1 ? 1 : 0)
Text(label)
Image(systemName: "info.circle.fill")
.opacity(info2 ? 1 : 0)
}
}
}
}
Я уверен, что есть лучший способ, но пока не нашел ничего, что подходит для работы в более сложных представлениях. Есть предложения?
Ответ или решение
Чтобы скрывать и показывать элементы в SwiftUI без нарушения расположения других элементов, можно использовать модификатор Hidden
. Ваша текущая реализация с использованием свойства opacity
действительно сохраняет размеры элементов, но может привести к тому, что визуальный порядок может быть не совсем удобным. Вместо этого, оптимально использовать условия для отображения или скрытия элементов, что позволит сохранить центрирование текста.
Ниже приведён модифицированный вариант вашего кода, в котором мы используем условное отображение для изображений:
import SwiftUI
struct ContentView: View {
@State var info1: Bool = false
@State var info2: Bool = false
@State var label: String = ""
var body: some View {
VStack {
TextField("Введите метку", text: $label)
.frame(width: 200)
Toggle("Инфо 1", isOn: $info1)
.frame(width: 100)
Toggle("Инфо 2", isOn: $info2)
.frame(width: 100)
HStack {
if info1 {
Image(systemName: "info.circle.fill")
}
Text(label)
if info2 {
Image(systemName: "info.circle.fill")
}
}
.frame(maxWidth: .infinity) // Центрирование HStack
}
.padding()
}
}
Объяснение:
-
Условное отображение элементов: Вместо использования
opacity
, мы используем условные операторыif
, чтобы показать или скрыть значкиImage
. Когдаinfo1
илиinfo2
равныtrue
, соответствующий значок отображается, и его размер занимает место в горизонтальном стекеHStack
. Когда переменная равнаfalse
, элемент не занимает место. -
Центрирование текста: Используя
frame(maxWidth: .infinity)
дляHStack
, вы можете гарантировать, что содержимое будет отцентрировано внутри стека, независимо от видимости значков. -
Гибкость для более сложных интерфейсов: Этот подход позволяет легко добавлять другие элементы и поддерживать хорошее выравнивание, делая код более понятным и легко масштабируемым.
Таким образом, вы сможете управлять показом и скрытием элементов без нарушения структуры и позиционирования других представлений в вашем интерфейсе.