Wie kann ich einen optionalen Wert in einer Bindung in Swift auspacken?

9

Ich erstelle eine App mit SwiftUI und möchte eine Möglichkeit, eine Binding<Value?>in eine Binding<Value> zu konvertieren .

In meiner App habe ich eine, AvatarViewdie weiß, wie man ein Bild für einen bestimmten Benutzer rendert.

struct AvatarView: View {
  @Binding var userData: UserData

  ...
}

Meine App enthält eine ContentView, die zwei Bindungen besitzt: ein Wörterbuch der Benutzer nach ID und die ID des Benutzers, dessen Avatar angezeigt werden soll.

struct ContentView: View {
  @State var userById: Dictionary<Int, UserData>
  @State var activeUserId: Int

  var body: some View {
    AvatarView(userData: $userById[activeUserId])
  }
}

Problem: Der obige Code wird nicht kombiniert, da er $userById[activeUserId]vom Typ ist Binding<UserData?>und AvatarViewa enthält Binding<UserData>.

Dinge, die ich versucht habe ...

  • $userById[activeUserId]!funktioniert nicht, weil es versucht, a auszupacken Binding<UserData?>. Sie können nur eine auspacken Optional, keine Binding<Optional>.

  • $(userById[activeUserId]!)funktioniert aus Gründen, die ich noch nicht verstehe, nicht, aber ich denke, dass etwas $zur Kompilierungszeit gelöst wird, sodass Sie scheinbar keinen beliebigen Ausdrücken voranstellen können $.

rjkaplan
quelle
Hast du es versucht $userById[activeUserId] as! Binding<UserData>?
Kamran
Danke für den Vorschlag! Ich denke, es würde wahrscheinlich gut funktionieren, aber ich würde es vorziehen, keine unsichere Besetzung zu machen. Wenn ich es versuche, erhalte ich eine Build-Warnung mit der Aufschrift "Umwandlung von Bindung <UserData?> In nicht verwandten Typ Bindung <Benutzerdaten>"
rjkaplan

Antworten:

10

Sie können diesen Initialisierer verwenden , der genau diesen Fall zu behandeln scheint - Konvertierung Binding<T?>in Binding<T>?:

var body: some View {
    AvatarView(userData: Binding($userById[activeUserId])!)
}

Ich habe das !Auspacken erzwungen, genau wie bei Ihren Versuchen, aber Sie können das auspacken, wie nilSie möchten. Der Ausdruck Binding($userById[activeUserId])ist vom Typ Binding<UserData>?.

Kehrmaschine
quelle