Как развернуть необязательное значение внутри привязки в Swift?


9

Я создаю приложение с использованием SwiftUI и хотел бы преобразовать a Binding<Value?>в Binding<Value>.

В моем приложении у меня есть, AvatarViewкоторый знает, как визуализировать изображение для конкретного пользователя.

struct AvatarView: View {
  @Binding var userData: UserData

  ...
}

Мое приложение содержит ContentViewдве привязки: словарь пользователей по идентификатору и идентификатор пользователя, аватар которого мы должны показывать.

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

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

Проблема: приведенный выше код не объединяется, потому что $userById[activeUserId]имеет тип Binding<UserData?>и AvatarViewпринимает Binding<UserData>.

Вещи, которые я пытался ...

  • $userById[activeUserId]!не работает, потому что пытается развернуть Binding<UserData?>. Вы можете только развернуть Optional, а не Binding<Optional>.

  • $(userById[activeUserId]!)не работает по причинам, которые я еще не понимаю, но я думаю, что что-то $решается во время компиляции, поэтому вы не можете использовать префикс произвольных выражений $.


Ты пробовал $userById[activeUserId] as! Binding<UserData>?
Кямран

Спасибо за предложение! Я думаю, что это, вероятно, будет работать нормально, но я бы предпочел не делать небезопасных бросков. Когда я пытаюсь это сделать, я получаю предупреждение о сборке, говорящее «Приведение из Binding <UserData?> К несвязанному типу Binding <UserData>»
rjkaplan

Ответы:


10

Вы можете использовать этот инициализатор , который, кажется, обрабатывает именно этот случай - преобразование Binding<T?>в Binding<T>?:

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

Я использовал !принудительное развертывание, как в ваших попытках, но вы можете развернуть его nilтак, как хотите. Выражение Binding($userById[activeUserId])имеет тип Binding<UserData>?.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.