SwiftUI Verständnisfrage?
Hallo,
Es geht um folgende Codezeilen:
struct Stars: View {
@Binding var rating: Int
var body: some View {
HStack {
ForEach(1 ..< 6) { value in
Button(action: {
self.rating = value
}){
Image(systemName: value <= self.rating ? "star.fill" : "star")
}
}
}
}
}
Grundsätzlich weiß ich was da passiert. Aber ich würde gerne wissen, wo definiert ist, wieviel Sterne ich an der Stelle angeklickt habe, bzw wie der ein Wert in die Variable "value" kommt. Es ist offenbar nicht die aktuelle Schleifen Iteration.
Kann mir bitte jemand Erleuchtung schenken?
1 Antwort
In der Button-Action.
Die Schleife produziert sechs Buttons. Jeder Button bekommt eine Action, die bei Klick ausgelöst wird. In der wird das Property rating auf den entsprechenden Wert von value gesetzt.
Der Wert von value wird bei der Definition der Action gekapselt, so wie es du vielleicht aus anderen Sprachen bei Lambda-Ausdrücken kennst. Das heißt, der Kontext der Action merkt sich den aktuellen Wert von value, der an sie übergeben wurde. Auch wenn value durch die Schleife weiter erhöht wird, ändert er sich für die jeweiligen Actions nicht.
Die Variable value ist übrigens eine Variable, die automatisch von der Schleife bei jedem Iterationsvorgang verändert wird. Die Schreibweise im Vergleich zu anderen Programmiersprachen ist nur anders.
C#
foreach (var item in items)
{
}
SwiftUI:
ForEach(items) { item in
}
Und da jeder Button eine eigene "rating" property hat, (...)
Nein, das nicht. Es wird in jedem Fall das rating-Property von Stars geändert.
Das, was an action übergeben wird:
action: { self.rating = value }
ist eine anonyme Funktion, die bei ihrer Definition Zugriff auf alle Elemente des äußeren Kontexts hat (also das rating-Property und value). Diese Elemente merkt sie sich. Wenn sie dann irgendwann einmal ausgeführt wird, kann sie auf die zwischengespeicherten Werte zugreifen.
Ja, das mit den Schleifen ist mir bewusst. Ah, jetzt sehe ich es auch :D
Und da jeder Button eine eigene "rating" property hat, wird bei einem klick die Iteration neu gestartet. Und solange der value kleiner <= der Wert des button ratings ist, ist der Stern ausgefüllt.
Die Syntax von SwiftUI ist schon hier und da Gewöhnungsbedürftig.