我有一个实现平等协议的类,它使用一个UUID字段进行比较:
class MemberViewModel {
private static var entities: [MemberViewModel] = []
private var entity: Member
let id = UUID()
init(_ entity: Member) {
self.entity = entity
}
static func members() -> [MemberViewModel] {
entities.removeAll()
try? fetch().forEach { member in
entities.append(MemberViewModel(member))
}
return entities
}
}
extension MemberViewModel: Equatable {
static func == (lhs: MemberViewModel, rhs: MemberViewModel) -> Bool {
return lhs.id == rhs.id
}
}然后,我有一个视图,创建图标,当点击这些图标时,应该显示一个笔画来表示它是“被选中的”:
struct MyView: View {
@State var selectedMember: MemberViewModel? = nil
var body: some View {
let members = MemberViewModel.members()
ScrollView(.horizontal, showsIndicators: true) {
HStack(alignment: .top, spacing: 4) {
ForEach (members, id: \.id) { member in
var isSelected: Bool = selectedMember == member
Circle()
.fill(Color(.red))
.frame(width: 48, height: 48)
.overlay() {
if isSelected {
Circle()
.stroke(Color(.black), lineWidth: 2)
}
}
.onTapGesture { selectedMember = member }
}
}
}
}
}我尝试过多种方法设置isSelected,包括another SO question中的以下内容
let isSelected = Binding<Bool>(get: { self.selectedMember == member }, set: { _ in })使用断点进行调试时,isSelected的值总是为false。
我使用的是XCode版本14.0.1 (14A400)和SWIFT5.7。
发布于 2022-10-28 10:46:11
将let members = MemberViewModel.members()放在var body: some View {...}前面,而不是放在里面,如下所示:
let members = MemberViewModel.members() // <-- here
var body: some View {
...
} 由于您奇怪的代码结构,每次刷新let members = MemberViewModel.members()时,body都会被重做。既然UUID是重新生成的..。您可以猜到,ids现在到处都是,不等于selectedMember。
换句话说,对象比较是有效的,但您并不是在比较您的想法。
发布于 2022-10-28 05:19:14
使用下面的示例,希望您能得到这个想法。
模型
struct Member {
let id = UUID()
}
extension Member: Equatable {
static func == (lhs: Member, rhs: Member) -> Bool {
return lhs.id == rhs.id
}
}
class MemberViewModel: ObservableObject {
// each time you update the entities, view vill be updated
@Published var entities: [Member] = []
func fetchMembers() {
entities.removeAll()
// your code to fetch members
try? fetch().forEach { member in
entities.append(member)
}
}
}MyView
struct MyView: View {
@StateObject private var modelData = MemberViewModel()
@State private var selectedMember: Member? = nil
var body: some View {
ScrollView(.horizontal, showsIndicators: true) {
HStack(alignment: .top, spacing: 4) {
ForEach (modelData.entities, id: \.id) { member in
Circle()
.fill(Color(.red))
.frame(width: 48, height: 48)
.overlay() {
if selectedMember == member {
Circle()
.stroke(Color(.black), lineWidth: 2)
}
}
.onTapGesture { selectedMember = member }
}
}
}.onAppear {
modelData.fetchMembers()
}
}
}https://stackoverflow.com/questions/74230084
复制相似问题