SwiftUI自定义ViewModel报Does not conform to protocol Hashable错误如何解决
问题原因
- 你声明了
DeclarationListViewModel遵守Hashable协议,但没有实现协议要求的==静态方法和hash(into:)方法,会触发编译报错。 - 要在 SwiftUI 的
ForEach中使用数组元素,需要让元素遵守Identifiable协议,或者显式给ForEach指定元素唯一标识的键路径,否则ForEach无法区分不同元素。
方案1:补全协议实现(推荐,适配ForEach直接使用)
修改代码如下:
import Foundation import SwiftUI public class DeclarationViewModel: ObservableObject { @Published var description: [DeclarationListViewModel]? init() { self.description = [DeclarationListViewModel]() } init(shortDescription: [DeclarationListViewModel]?) { self.description = shortDescription } } public class DeclarationListViewModel: ObservableObject, Identifiable, Hashable { // 新增唯一标识,自动生成无需手动赋值 public let id = UUID() @Published var yesNo: Bool? @Published var title: String? // 实现Hashable协议要求的判等方法 public static func == (lhs: DeclarationListViewModel, rhs: DeclarationListViewModel) -> Bool { lhs.id == rhs.id } // 实现Hashable协议要求的哈希计算方法 public func hash(into hasher: inout Hasher) { hasher.combine(id) } }
方案2:调整ForEach写法(如果不需要保留Hashable遵守)
如果你的业务不需要用到Hashable能力,可以直接删掉Hashable的协议声明,在ForEach中显式指定id为\.id即可:
public class DeclarationListViewModel: ObservableObject, Identifiable { public let id = UUID() @Published var yesNo: Bool? @Published var title: String? }
ForEach使用示例
修改后你的ForEach可以直接这样写:
// 假设declarationViewModel是你当前视图持有的DeclarationViewModel实例 ForEach(declarationViewModel.description ?? []) { item in // 你的列表项视图,如果要响应item内部属性的变化,需要在子视图中用@ObservedObject接收item DeclarationItemView(item: item) }
如果子视图需要响应yesNo、title的更新,子视图的定义参考:
struct DeclarationItemView: View { @ObservedObject var item: DeclarationListViewModel var body: some View { Text(item.title ?? "") } }
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

