Swift Charts:使Int枚举遵循Plottable协议以显示图例却无法正常显示的问题
解决Swift Charts中自定义Int枚举作为Plottable时图例不显示的问题
你的枚举实现Plottable的思路是对的,但图例不显示的核心原因是当前图表只渲染了Type.first的数据,Swift Charts无法识别到还有Type.second这个类别存在,即使你在chartForegroundStyleScale中定义了它。另外,我们可以简化Plottable的实现,因为Swift Charts已经为RawRepresentable类型提供了默认支持。
步骤1:简化枚举的Plottable实现
对于遵循RawRepresentable且原始类型是Plottable(比如Int)的枚举,你不需要手动实现Plottable的两个方法,Swift Charts会自动提供默认实现。修改后的枚举代码如下:
enum Type: Int, CaseIterable, Identifiable, Plottable { var id: Int { rawValue } case first = 32 case second = 434 }
步骤2:让图表识别所有枚举类别
要让图例显示所有定义的样式,需要确保图表知道所有可能的枚举case,即使某个case没有对应的数据。你可以通过两种方式实现:
方式一:显式处理所有枚举case的数据
在图表中分别处理每个枚举case的数据,即使数据为空也保留结构,这样图表会识别到所有类别:
Chart { // 处理Type.first的数据 if let firstObjects = object.objects(type: .first) { ForEach(firstObjects) { object in BarMark( x: .value("#", object.indexInSegment), y: .value("Distance", object.distance) ) .foregroundStyle(by: .value("Type", object.type)) } } // 处理Type.second的数据(即使为空也保留) if let secondObjects = object.objects(type: .second) { ForEach(secondObjects) { object in BarMark( x: .value("#", object.indexInSegment), y: .value("Distance", object.distance) ) .foregroundStyle(by: .value("Type", object.type)) } } } .chartLegend(position: .bottom, spacing: 8) .chartForegroundStyleScale([ Type.first: Color.pink, Type.second: Color.yellow ]) .frame(minHeight: 200)
方式二:添加透明占位标记(适用于某些case无数据的场景)
如果某个枚举case没有对应的数据,你可以添加一个透明的占位标记,让图表识别到这个类别:
Chart { // 现有数据渲染逻辑 if let allObjects = object.objects(type: Type.first) { ForEach(allObjects) { object in BarMark( x: .value("#", object.indexInSegment), y: .value("Distance", object.distance) ) .foregroundStyle(by: .value("Type", object.type)) } } // 为所有枚举case添加透明占位 Type.allCases.forEach { type in if object.objects(type: type)?.isEmpty ?? true { BarMark( x: .value("#", 0), y: .value("Distance", 0) ) .foregroundStyle(by: .value("Type", type)) .opacity(0) // 隐藏占位标记,不影响图表显示 } } } .chartLegend(position: .bottom, spacing: 8) .chartForegroundStyleScale([ Type.first: Color.pink, Type.second: Color.yellow ]) .frame(minHeight: 200)
额外检查点
- 确保
foregroundStyle(by:)的标签(这里是"Type")保持一致,图表会用这个标签来关联图例和样式。 - 如果你的图表中完全没有任何数据,图例也不会显示,所以要保证至少有一个case有数据,或者通过占位标记让图表识别所有类别。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

