我目前正在尝试更新我的应用程序小部件以支持 iOS 18 的有色主屏幕自定义选项。为此,我尝试在需要的地方应用 .widgetAccentable() 。然而,我在使用 Swift Charts 时遇到了一个问题。
我的代码目前看起来像这样:
Chart {
ForEach(data, id: \.id) { day in
BarMark(
x: .value("###", day.date, unit: .day),
y: .value("###", day.value)
)
.cornerRadius(10.0)
.foregroundStyle(Color.blue.gradient)
.alignsMarkStylesWithPlotArea()
.annotation {
Text(day.value.description)
.font(.subheadline)
}
}
}
.widgetAccentable()
.chartYAxis(.hidden)
.chartXAxis {
AxisMarks(values: .stride(by: .day)) { value in
AxisValueLabel(format: Date.FormatStyle().weekday(.short), centered: true)
}
}
问题是我只能将 .widgetAccentable() 应用于整个图表。这将为所有内容(条形标记、标签、轴...)着色。
我想要实现的是仅对条形标记进行着色,而不对标签和其他所有内容进行着色......这些应该保持黑/白单色。
有什么办法可以做到这一点吗?
widgetAccentable
尚不支持图表。它的文档解释了它是如何工作的,
应用颜色时,系统将小部件的视图视为模板图像。它忽略视图的颜色——根据视图的 Alpha 通道渲染新颜色。
因此,除非它成为
ChartContent
的修饰符,否则您不能 just 将小节放入重音组中。
解决方法是构建图表的精确副本,除了条形图之外的所有内容都是透明的。然后将
widgetAccentable
放在覆盖层上。
var body: some View {
ZStack {
chart(accented: false)
chart(accented: true)
}
}
func chart(accented: Bool) -> some View {
Chart {
ForEach(data) { day in
BarMark(
x: .value("###", day.date, unit: .day),
y: .value("###", day.value)
)
.cornerRadius(10.0)
.alignsMarkStylesWithPlotArea()
.annotation {
Text(day.value.description)
.font(.subheadline)
.opacity(accented ? 0 : 1)
}
}
}
.chartYAxis(.hidden)
.chartXAxis {
AxisMarks(values: .stride(by: .day)) { value in
AxisValueLabel(format: Date.FormatStyle().weekday(.short), centered: true)
.foregroundStyle(accented ? .clear : .black)
}
}
.widgetAccentable(accented)
}