¿Cómo puedo desenvolver un valor opcional dentro de un enlace en Swift?

9

Estoy creando una aplicación usando SwiftUI y me gustaría una forma de convertir Binding<Value?>a a Binding<Value>.

En mi aplicación tengo una AvatarViewque sabe cómo representar una imagen para un usuario en particular.

struct AvatarView: View {
  @Binding var userData: UserData

  ...
}

Mi aplicación posee un ContentViewenlace que posee dos enlaces: un diccionario de usuarios por identificación y la identificación del usuario cuyo avatar deberíamos mostrar.

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

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

Problema: el código anterior no se combina porque $userById[activeUserId]es de tipo Binding<UserData?>y AvatarViewabarca a Binding<UserData>.

Cosas que probé ...

  • $userById[activeUserId]!no funciona porque está tratando de desenvolver a Binding<UserData?>. Solo puedes desenvolver un Optional, no un Binding<Optional>.

  • $(userById[activeUserId]!)no funciona por razones que aún no entiendo, pero creo que algo $se resuelve en el momento de la compilación, por lo que parece que no puede prefijar expresiones arbitrarias con $.

rjkaplan
fuente
¿Lo intentaste $userById[activeUserId] as! Binding<UserData>?
Kamran
¡Gracias por la sugerencia! Creo que probablemente funcionaría bien, pero preferiría no hacer un reparto inseguro. Cuando lo intento, recibo una advertencia de compilación que dice "¿Transmitir desde Binding <UserData?> A un tipo no relacionado Binding <UserData>"
rjkaplan

Respuestas:

10

Puede usar este inicializador , que parece manejar este caso exacto, convirtiendo Binding<T?>a Binding<T>?:

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

Solía !forzar el desenvolvimiento, al igual que en tus intentos, pero puedes desenvolver lo nilque quieras. La expresión Binding($userById[activeUserId])es de tipo Binding<UserData>?.

Barrendero
fuente