Как создать привязку Toggle из массива объектов? - PullRequest
0 голосов
/ 23 октября 2019

Есть несколько полезных вопросов по этой теме, но все, что я обнаружил, используют устаревший синтаксис из более ранних бета-версий (например, BindableObject) или не требуют передачи привязки (например, к Toggle).

Я хочу создать список переключателей, которые связаны с элементами в массиве. Я перепробовал много методов, но синтаксис никогда не корректен. Версия ниже наиболее точно соответствует ответам на существующий вопрос .

struct Item: Identifiable {
    var id: String { self.name }
    var name: String
    var enabled: Bool
}

final class ItemSet: ObservableObject {
    @Published var items: [Item]

    init() {
        items = [
            Item(name: "aaa", enabled: true),
            Item(name: "bbb", enabled: false),
            Item(name: "ccc", enabled: true)
        ]
    }
}

var myItems = ItemSet()

struct ContentView: View {
    @ObservedObject var items: ItemSet

    var body: some View {
        List {
            ForEach(items.items) { item in
                Toggle(item.name, isOn: $item.enabled)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(items: myItems)
    }
}

Ошибка компилятора, которую я получаю в Xcode 11.1:

Использование неразрешенногоидентификатор '$ item'

в строке, где определен Toggle.

У меня сложилось впечатление, что каждый Item сам по себе должен быть ObservableObject с *Параметр 1018 *, но я также не смог заставить его работать, и все ответы на stackoverflow, кажется, говорят, что не следует делать Item сам ObservableObject.

Любая помощь будет высоко ценится.

1 Ответ

1 голос
/ 24 октября 2019

Вы путаете оболочку свойства для items (которая является субъектом текущего значения) с параметром привязки, которого ожидает Toggle. См. Исправленную реализацию с привязкой ниже:

import SwiftUI
import Combine

struct Item: Identifiable {
  var isEnabled: Binding<Bool>
  var id: String { self.name }
  var name: String
  init(name: String, enabled enabledValue: Bool) {
    self.name = name
    let enabled = CurrentValueSubject<Bool, Never>(enabledValue)
    isEnabled = Binding<Bool>(
      get: { enabled.value },
      set: { enabled.value = $0}
    )
  }
}

final class ItemSet: ObservableObject {
  @Published var items: [Item]

  init() {
    items = [
      Item(name: "aaa", enabled: true),
      Item(name: "bbb", enabled: false),
      Item(name: "ccc", enabled: true)
    ]
  }
}

var myItems = ItemSet()

struct ContentView: View {
  @ObservedObject var items: ItemSet

  var body: some View {
    List {
      ForEach(items.items) { item in
        Toggle(isOn: item.isEnabled, label: { Text (item.name) })
      }
    }
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView(items: myItems)
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...