Come posso scartare un valore opzionale all'interno di un'associazione in Swift?


9

Sto creando un'app utilizzando SwiftUI e vorrei un modo per convertire un Binding<Value?>in Binding<Value>.

Nella mia app ne ho uno AvatarViewche sa come rendere un'immagine per un particolare utente.

struct AvatarView: View {
  @Binding var userData: UserData

  ...
}

La mia app contiene un ContentViewche possiede due associazioni: un dizionario di utenti per ID e l'id dell'utente di cui dovremmo mostrare l'avatar.

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

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

Problema: il codice sopra riportato non si combina perché $userById[activeUserId]è di tipo Binding<UserData?>e contiene AvatarViewa Binding<UserData>.

Cose che ho provato ...

  • $userById[activeUserId]!non funziona perché sta cercando di scartare un Binding<UserData?>. Puoi solo scartare un Optional, non un Binding<Optional>.

  • $(userById[activeUserId]!)non funziona per motivi che non ho ancora capito, ma penso che qualcosa al momento $sia stato risolto in modo da non poter prefiggere espressioni arbitrarie $.


Ci hai provato $userById[activeUserId] as! Binding<UserData>?
Kamran

Grazie per il suggerimento! Penso che probabilmente funzionerebbe bene, ma preferirei non fare un cast non sicuro. Quando lo provo ricevo un avviso di build che dice "Trasmetti da Binding <UserData?> A tipo non correlato Binding <UserData>"
rjkaplan,

Risposte:


10

Puoi usare questo inizializzatore , che sembra gestire questo caso esatto, convertendolo Binding<T?>in Binding<T>?:

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

Ho usato !per forzare lo scartamento, proprio come nei tuoi tentativi, ma potresti scartare quello nilche vuoi. L'espressione Binding($userById[activeUserId])è di tipo Binding<UserData>?.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.