#swift #swiftui
#swift #swiftui
Вопрос:
Почему нельзя назначить необязательный параметр?
Индекс был выделен, но значение по-прежнему не отображается
Помогите мне, спасибо!
struct TestView: View {
@State private var index: Int? = nil
@State private var show: Bool = false
var body: some View {
VStack {
Text("Hello, world!")
.onTapGesture {
self.index = 1
self.show = true
print(self.index as Any)
}
}
.fullScreenCover(isPresented: $show) {
if let index = self.index {
Text("value:(index)")
} else {
Text("not value")
}
}
}
}
Версия Xcode 12.0 beta 2
Комментарии:
1.
if self.index != nil
не делайте этого, узнайте об условном выжидании,if let index = self.index { ... }
2. @Alexander-Переустановите Monica, но можете ли вы сделать это при закрытии в представлении SwiftUI?
3. @Alexander-Переустановите monica спасибо, я пытался развернуть, но индекс не значение, запутался!
4. @JoakimDanielson Хорошая мысль, я помню, что по этому поводу были проблемы. Разве они не решили это, хотя?
5. @Alexander-Переустановите Monica, По крайней мере, не в Xcode 11, я еще не тестировал Xcode 12 / SwiftUI 2.0.
Ответ №1:
SwiftUI полагается на @State
переменную, заставляющую body
средство получения пересчитываться при его изменении. Чтобы это сработало, body
средство получения должно зависеть определенным образом от @State
переменной. Проблема в вашем коде в том, что это не так.
Чтобы убедиться в этом, мы можем сократить ваш код до более простого примера:
struct ContentView: View {
@State var message = "Hey"
@State var show: Bool = false
var body: some View {
VStack {
Button("Test") {
message = "Ho"
show = true
}
}
.sheet(isPresented: $show) {Text(message)}
}
}
Мы меняем message
на Ho, но когда отображается таблица, на ней по-прежнему написано Hey. Это потому, что ничего не произошло для body
пересчета. Вы могли бы сказать: А как насчет фразы Text(message)
? Да, но это в закрытии; он уже был вычислен и message
уже был захвачен.
Чтобы убедиться в правильности того, что я говорю, просто добавьте текст, отображаемый message
непосредственно в главном интерфейсе:
struct ContentView: View {
@State var message = "Hey"
@State var show: Bool = false
var body: some View {
VStack {
Button("Test") {
message = "Ho"
show = true
}
Text(message)
}
.sheet(isPresented: $show) {Text(message)}
}
}
Теперь ваш код работает! Конечно, мы также отображаем нежелательный текст в интерфейсе, но суть в том, что простого Text(message)
, не в замыкании, достаточно, чтобы весь body
получатель был пересчитан при message
изменениях. Итак, мы правильно объяснили явление, о котором вы спрашиваете.
Итак, каково реальное решение? Как мы можем заставить content
замыкание работать так, как мы ожидаем, без добавления дополнительного текста в интерфейс? Один из способов такой:
struct ContentView: View {
@State var message = "Hey"
@State var show: Bool = false
var body: some View {
VStack {
Button("Test") {
message = "Ho"
show = true
}
}
.sheet(isPresented: $show) {[message] in Text(message)}
}
}
Включив message
в список захвата для нашего закрытия, мы заставляем body
средство получения зависеть от message
переменной, и теперь код ведет себя так, как требуется.
Комментарии:
1. Отлично!, Отлично!, Спасибо!