如何获取经scaleEffect变换的Swift Chart中正确的点击像素?
问题:Swift Chart 翻转后点击坐标匹配异常
为了让Swift Chart在ScrollView初始显示时滚动到右侧,我给图表添加了scaleEffect(x: -1)进行水平翻转,再给外层ScrollView添加同样的翻转来还原视觉效果。但这样做后,chartOverlay中的onTapGesture无法获取用户实际点击的逻辑像素,导致打印的日期不正确。
我有一个临时解决方案,但它无法处理两种场景:
- 图表尺寸小于屏幕时自动扩展的情况
- 图表左右两侧存在不可预测间距的情况
另外我尝试过用onAppear调用scrollTo直接滚动到右侧作为替代方案,但这个方案存在bug,在iOS16上表现尤为明显。
示例代码
import SwiftUI import Charts struct ContentView: View { var dates = (0..<100).map { Calendar.current.date(byAdding: .day, value: $0, to: Date())! } var body: some View { GeometryReader { geo in ScrollViewReader { proxy in ScrollView(.horizontal) { HStack(spacing:0) { Chart { ForEach(dates, id:\.self) { date in LineMark(x: .value("day", date), y: .value("value", 1)) } } .chartXAxis { AxisMarks(preset: .extended, position: .bottom, values: .stride (by: .day)) { value in let label = value.as(Date.self)!.formatted(.dateTime.day()) + "\n" + value.as(Date.self)!.formatted(.dateTime.month()) AxisValueLabel(collisionResolution: .greedy) { Text(label) } } } .frame(minWidth: 40.0*CGFloat(dates.count)+10.0, maxWidth:.infinity, minHeight: geo.size.height, maxHeight:.infinity, alignment: .center) .scaleEffect(x: -1, y: 1) } .frame(minWidth: geo.size.width, maxWidth:.infinity, maxHeight:.infinity, alignment:.center) .chartOverlay { proxy in GeometryReader { geometry in Rectangle().fill(.clear).contentShape(Rectangle()) .onTapGesture { location in onTap(at: location, geometry: geometry, proxy: proxy) } } } } .frame(maxWidth:.infinity, maxHeight:.infinity, alignment:.center) .scaleEffect(x: -1, y: 1) } } } func onTap(at: CGPoint, geometry: GeometryProxy, proxy: ChartProxy) { let origin = geometry[proxy.plotAreaFrame].origin let selectedDate = proxy.value(atX: at.x - origin.x, as: Date.self) if selectedDate != nil { print("1 tapped on date \(selectedDate)") // 无翻转时正常工作 } let selectedDate2 = proxy.value(atX: (40.0*CGFloat(dates.count)+10.0 - at.x) - origin.x, as: Date.self) if selectedDate2 != nil { print("2 tapped on date \(selectedDate2)") // 翻转后无法正常工作 } } }
内容的提问来源于stack exchange,提问作者John Cashew
相关产品推荐
相关产品推荐

