swift - 如何从对象数组创建切换绑定(bind)?

标签 swift swiftui

关于这个主题有几个有用的问题,但我发现的所有问题要么使用早期测试版中已弃用的语法(例如,BindableObject),要么不需要传递绑定(bind)(例如,传递给 Toggle)。

我想创建一个绑定(bind)到数组中元素的切换列表。我试过很多方法,但语法永远都不正确。以下版本与 an existing question 的答案最接近.

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 中得到的编译器错误是:

Use of unresolved identifier '$item'

在定义 Toggle 的行上。

我的印象是每个 Item 本身都需要是一个带有 @Published var enabled: Bool 参数的 ObservableObject,但是我也无法让它工作,所有 stackoverflow 的答案似乎都在说避免制作 Item 本身 ObservableObject

如有任何帮助,我们将不胜感激。

最佳答案

您将 items 的属性包装器(这是一个当前值主题)与 Toggle 期望的绑定(bind)参数混淆了。请参阅下面带有绑定(bind)的更正实现:

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)
  }
}

关于swift - 如何从对象数组创建切换绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58530244/

相关文章:

ios - heightForHeaderInSection 中的未捕获异常

ios - 如何检查主机服务器是否支持 ResumeData

ios - UICollectionView 中仅某些单元格之间的自定义间距

ios - 在 Parse iOS 中更新对象,[错误] : Object not found

ios - 我可以将私有(private)变量传递给将通过 Storyboard 实例化的 UIViewController 吗?

ios - SwiftUI 中的堆叠 View

NavigationUI中的SwiftUI自定义动画过渡?

ios - SwiftUI 移除 NavigationBar 底部边框

SwiftUI - 如何在@ObservableObject 中获取@EnvironmentObject 数据

ios - TextEditor 在 SwiftUI 中被键盘遮挡