存储的属性类型“CGPoint”不符合协议“Hashable”,

时间:2021-06-14 17:22:58

标签: swift swiftui hashable

想象一个卡片板。所有卡片都在我称为 CardBoard 的视图中。

所有卡片都在一个数组上:

var cards:[Card]

每张卡片都有自己的位置。

这是卡片

struct Card: View {
  let id = UUID()
  
  var name:String
  var code:String
  var filename:String
  var position = CGPoint(x: 200, y: 250)
  
  
  init(name:String, code:String, filename:String) {
    self.name = name
    self.code = code
    self.filename = filename
  }
  
  
  var body: some View {
    Image(filename)
      .position(position)
  }
}

现在我想在屏幕上绘制它们。

var body: some View {
  ZStack {
    ForEach(cards, id:\.self) {card in
       
    }
  }
}

当我尝试这个时,Xcode 告诉我

Generic struct 'ForEach' requires that 'Card' conform to 'Hashable'

当我将 Hashable 添加到 Card

struct Card: View, Hashable {

1. Stored property type 'CGPoint' does not conform to protocol 'Hashable', preventing synthesized conformance of 'Card' to 'Hashable'

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

问题是您的 Cardpoint 无法自动合成,因为它是 CGPoint。您是否尝试过扩展 CGPoint 以符合 Hashable

关于为 CGPoint 创建散列逻辑的讨论非常有用:https://codereview.stackexchange.com/questions/148763/extending-cgpoint-to-conform-to-hashable

答案 1 :(得分:0)

谢谢大家,但由于发布链接作为解决方案不好,我在这里发布:

解决方案是使视图可哈希并添加:

extension CGPoint : Hashable {
  public func hash(into hasher: inout Hasher) {
    hasher.combine(x)
    hasher.combine(y)
  }
}

答案 2 :(得分:0)

有很多类型需要相同的处理(通常称为 2 元组)。例如

extension CGPoint: HashableSynthesizable { }
extension CLLocationCoordinate2D: HashableSynthesizable { }
extension MKCoordinateRegion: HashableSynthesizable { }
extension MKCoordinateSpan: HashableSynthesizable { }
/// A type whose `Hashable` conformance could be auto-synthesized,
/// but either the API provider forgot, or more likely,
/// the API is written in Objective-C, and hasn't been modernized.
public protocol HashableSynthesizable: Hashable { }

public extension HashableSynthesizable {
  static func == (hashable0: Self, hashable1: Self) -> Bool {
    zip(hashable0.hashables, hashable1.hashables).allSatisfy(==)
  }

  func hash(into hasher: inout Hasher) {
    hashables.forEach { hasher.combine($0) }
  }
}

private extension HashableSynthesizable {
  var hashables: [AnyHashable] {
    Mirror(reflecting: self).children
      .compactMap { $0.value as? AnyHashable }
  }
}