使用 chartXSelection 为 Swift Charts 添加交互功能
了解如何使用 chartXSelection 为 Swift Charts 添加交互功能。
在 iOS 17 中,Apple 为 SwiftUI 的 Charts 框架引入了新的 .chartXSelection
修饰器。这个修饰器的主要用途是允许开发者在图表中捕获用户对 X 轴数据的选择,从而实现更丰富的交互功能。
chartXSelection 使用场景
例如,我们有如下示例代码:
var body: some View {
VStack(alignment: .leading) {
Text("周度销售额")
.font(.headline)
.padding(.leading)
Chart(data) { item in
LineMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
}
.frame(height: 300)
.chartScrollableAxes(.horizontal)
.chartScrollPosition(initialX: "第10周")
.chartXAxis {
AxisMarks(values: .automatic(desiredCount: 8)) { value in
AxisValueLabel()
}
}
.padding()
}
}
上述代码创建了一个常规的折线图,并使用 chartScrollableAxes 修饰器添加了横向滑动功能:
上面这个图表很简洁的,但无法获取到每周具体的销售额。为了让图表功能更加完善,我们可以增加:当用户点击某个数据时,能显示该数据更具体的注释信息,类似 Apple 健康应用中的效果:
为了实现上述功能,就需要使用到 chartXSelection 修饰器。
使用 chartXSelection 修饰器
添加垂直标尺标注
chartXSelection 修饰器可用于在用户与图表交互时,获取他们在 X 轴上的选择位置。通过绑定(Binding)的方式,chartXSelection 可以实时获取和设置选中的值,同时支持点击和拖动操作。
为了实现类似上述效果,我们需要做以下工作:
1. 定义选中数据的状态变量
首先,创建两个 @State 变量,用于保存 chartXSelection 返回的选中数据:
@State private var selectedWeek: String?
@State private var selectedSales: Double?
2. 在图表中应用 chartXSelection
chartXSelection 本身仅用于获取数据,不会自动更新 UI。因此,需要手动添加 RuleMark,用于显示选中时的垂直标尺标注。
实例代码:
@State private var selectedWeek: String?
@State private var selectedSales: Double?
var body: some View {
VStack(alignment: .leading) {
Text("周度销售额")
.font(.headline)
.padding(.leading)
Chart(data) { item in
LineMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
if let week = selectedWeek,
"第\(item.week)周" == week
{
RuleMark(
x: .value("选中周", "第\(item.week)周")
)
.foregroundStyle(.gray.opacity(0.3))
.lineStyle(StrokeStyle(lineWidth: 2))
}
}
.frame(height: 300)
.chartScrollableAxes(.horizontal)
.chartScrollPosition(initialX: "第10周")
.chartXAxis {
AxisMarks(values: .automatic(desiredCount: 8)) { value in
AxisValueLabel()
}
}
.chartXSelection(value: $selectedWeek)
.padding()
}
}
添加注释框
为了更直观地显示选中信息,可以使用 PointMark 搭配 .annotation 添加数据标注: