Como posso desembrulhar um valor opcional dentro de uma ligação no Swift?

9

Estou criando um aplicativo usando o SwiftUI e gostaria de converter um Binding<Value?>para um Binding<Value>.

No meu aplicativo, eu tenho um AvatarViewque sabe como renderizar uma imagem para um usuário específico.

struct AvatarView: View {
  @Binding var userData: UserData

  ...
}

Meu aplicativo possui um ContentViewque possui duas ligações: um dicionário de usuários por ID e o ID do usuário cujo avatar devemos mostrar.

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

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

Problema: o código acima não combina porque $userById[activeUserId]é do tipo Binding<UserData?>e AvatarViewleva a Binding<UserData>.

Coisas que eu tentei ...

  • $userById[activeUserId]!não funciona porque está tentando desembrulhar a Binding<UserData?>. Você só pode desembrulhar um Optional, não um Binding<Optional>.

  • $(userById[activeUserId]!)não funciona por razões que ainda não entendi, mas acho que algo $foi resolvido no momento da compilação, para que você não consiga prefixar expressões arbitrárias com $.

rjkaplan
fonte
Você tentou $userById[activeUserId] as! Binding<UserData>?
Kamran
Obrigado pela sugestão! Eu acho que provavelmente funcionaria bem, mas eu preferiria não fazer um elenco inseguro. Quando eu tento isso eu recebo um aviso de compilação dizendo "Elenco de ligação <UserData?> Para tipo não relacionado Encadernação <UserData>"
rjkaplan

Respostas:

10

Você pode usar esse inicializador , que parece lidar com esse caso exato - convertendo Binding<T?>para Binding<T>?:

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

Eu costumava !forçar o desembrulhar, assim como em suas tentativas, mas você pode desembrulhar da maneira nilque quiser. A expressão Binding($userById[activeUserId])é do tipo Binding<UserData>?.

Vassoura
fonte