分段选择器视图选择具有相同索引的部分中的所有行
Posted
技术标签:
【中文标题】分段选择器视图选择具有相同索引的部分中的所有行【英文标题】:sectioned pickerview chooses all rows in sections with same index 【发布时间】:2020-12-30 12:18:02 【问题描述】:我正在尝试创建一个包含部分的PickerView
每个项目都符合“id”,我用项目的 id 标记Text
(这是唯一的,我验证没有冲突)
PickerView
似乎忽略了我分配的标签,并为每个部分选择具有相同对应索引的所有行
我还尝试使用随机 UUID 标记每个项目以检查行为,它似乎继续
struct ExperimentPickerView: View
@StateObject var localExperiment = RunningExperiment.active
@StateObject var experiments = RemoteExperiments.instance
@State var picked : Int = -1
var body: some View
Picker("active", selection: $picked)
ForEach(Array(experiments.experiments.enumerated()), id: \.offset) i,experiment in
Section(header: Text("\(experiment.name)"))
ForEach(Array(experiment.variations.enumerated()), id: \.offset) j,variation in
// Text("\(variation.name) \(variation.id)").tag(variation.id)
Text("\(variation.name) \(variation.id)").tag(UUID().description)
.id(picked).onReceive([self.picked].publisher.first()) (value) in
print(value) // prints the row number and not the id of the element
struct Experiment : Codable, Equatable, Identifiable
var id: Int
var hasher = Hasher()
name.hash(into: &hasher)
variations.hash(into: &hasher)
return hasher.finalize()
let name : String
let variations: [Variation]
enum CodingKeys: String, CodingKey
case name
case variations
init(from decoder: Decoder) throws
let container = try decoder.container(keyedBy: CodingKeys.self)
let n = try container.decode(String.self, forKey: .name)
name = n
let a = try container.decode(AnyCodable.self, forKey: .variations)
print(a)
let b = a.value as! [[String:Any]]
var vars = [Variation]()
for v in b
if let na = v["name"], let nna = na as? String
vars.append(Variation(name: nna, experiment: n))
variations = vars
struct Variation: Codable, Equatable, Identifiable, Hashable
var id: Int
var hasher = Hasher()
name.hash(into: &hasher)
experiment.hash(into: &hasher)
let hashValue = hasher.finalize()
return hashValue
let name: String
var experiment: String
enum CodingKeys: String, CodingKey
case name, experiment
【问题讨论】:
【参考方案1】:tag
应该与selection
类型相同,因为它用于匹配选取的行。并且id
在这种情况下不应该被修改,因为它会完全重新初始化选择器。
提供的代码不可测试,因此这里只是一个解决方案演示(您的场景的简化复制)。
使用 Xcode 12.1 / ios 14.1 测试。
struct Pair: Hashable
var section = ""
var row = -1
struct ExperimentPickerView: View
var sections = ["A", "B", "C"]
var rows = Array(0..<5)
@State private var picked = Pair(section: "B", row: 2) // << here !! (initialised demo)
var body: some View
Picker("active", selection: $picked)
ForEach(sections, id: \.self) section in
Section(header: Text("\(section)").bold())
ForEach(rows, id: \.self) i in
Text("\(section) \(i)")
.tag(Pair(section: section, row: i)) // << match !!
.onReceive([self.picked].publisher.first()) (value) in
print(value)
【讨论】:
它们都是 int 类型且哈希值不变 UUID 只是测试它的行为方式。但是使用“variation.id”会产生一个唯一的 Int,它也与“picked”的类型相同 我将它修改为从 \.offset 开始工作,它开始工作了?♂️以上是关于分段选择器视图选择具有相同索引的部分中的所有行的主要内容,如果未能解决你的问题,请参考以下文章