Вы можете иметь операторы if в конструкторе представлений Group
. Я сделал пример, чтобы проиллюстрировать:
var label1 = "label 1"
@State var label2: String?
var label3: String? = "label 3"
var body: some View {
VStack {
Text(label1)
Group {
if label2 != nil {
Text(label2!)
}
if label3 != nil {
Text(label3!)
}
}
Button(action: {
self.label2 = "Button pressed!"
}) {
Text("Press me!")
}
}
}
Конечно, в этом примере вы могли бы просто сделать Text(label2 ?? "")
, но был бы пробел, где Text
до тех пор, пока label2
не будет иметь значениеа также, в более сложных ситуациях, это обеспечивает большую гибкость. Если вы запустите этот код, вы увидите «Метка 1» непосредственно над «Меткой 3», а если вы нажмете кнопку «Кнопка нажата!»появится между "Label 1" и "Label 3".
В основном, если label2
равен nil, не будет пустого места, где будет метка, когда она имеет значение, вместо этогоне будет пробела, и когда label2
будет присвоено значение, все выше и ниже того, где оно должно быть, сместится, чтобы приспособиться к нему.
В предоставленном вами коде вы можете изменить его на:
HStack {
Group {
if profile.height != nil {
TagBox(field: "height", value: String(profile.height!))
}
}
TagBox(field: "nationality", value: profile.nationality)
Spacer()
}.padding(.horizontal)
Хорошая особенность этого решения заключается в том, что в сценарии вы можете делать более сложные вещи, когда значение равно нулю (или нет), и даже предоставлять представление по умолчанию, если значение равно нулю (в моем примереэто будет эквивалентно добавлению else
для оператора if
с Button
, Text
и т. д. внутри тела else
).
Один недостатокчто вам нужно явно развернуть опциональные объекты, что не должно быть проблемой, потому что оператор if позаботится о том, чтобы убедиться, что он не равен nil, но я все же нахожу, что необязательное связывание - это, как правило, более чистый путь для развертывания опциональных файлов. 1025 * Редактировать :
Если вы действительно не хотите явно развертывать дополнительные опции, вы можете использовать ViewBuilder
s:
var label1 = "label 1"
@State var label2: String?
var label3: String? = "label 3"
var body: some View {
VStack {
Text(label1)
Group {
self.conditionalText(self.label2)
if label3 != nil {
Text(label3!)
}
}
Button(action: {
self.label2 = "Button pressed!"
}) {
Text("Press me!")
}
}
}
func conditionalText(_ text: String?) -> some View {
if let text = text {
return ViewBuilder.buildIf(Text(text))
} else {
print("Text is nil")
}
let view: Text? = nil
return ViewBuilder.buildIf(view)
}
Этот метод также показывает, как вы можете иметьисполняемый код внутри Group
, если он находится внутри функции, которая возвращает представление.