[英]Is there anyway to detect hovering gesture on `BarMark` in SwiftUI?
我正在尝试实现一种方法来检测 SwiftUI 中Chart
上的悬停手势。
起初我尝试向BarMark
添加.onHover()
修饰符,如下所示,但它似乎不起作用,因为BarMark
不符合View
Protocol 而.onHover()
定义为View
。
Chart(modules) { module in
BarMark(x: .value("name", module.name), y: .value("Score", module.score)).onHover { over in
details = module.name
} // gives error
}
那么这是否意味着如果我想在图表上显示用户 hover 时的其他数据,那么我必须创建自己的图表而不是使用Chart
框架中的Charts
?
您可以使用.chartOverlay
和.onContinuousHover
尝试这种方法。 您将必须调整位置计算以满足您的目的。
struct ContentView: View {
let measurement: [Measurement] = [
Measurement(id: "1", val: 11.2),
Measurement(id: "2", val: 22.2),
Measurement(id: "3", val: 38.2)
]
@State var select = "0"
@State var isHovering = false
var body: some View {
Chart {
ForEach(measurement) { data in
BarMark(x: .value("Time", data.id), y: .value("val", data.val))
.foregroundStyle(select == data.id ? .blue : .red)
}
}
.chartOverlay { proxy in
GeometryReader { geometry in
ZStack(alignment: .top) {
Rectangle().fill(.clear).contentShape(Rectangle())
.onContinuousHover { phase in
switch phase {
case .active(let location):
bar(at: location, proxy: proxy, geometry: geometry)
isHovering = true
case .ended:
isHovering = false
}
}
}
}
}
}
func bar(at location: CGPoint, proxy: ChartProxy, geometry: GeometryProxy) {
let xPosition = location.x - geometry[proxy.plotAreaFrame].origin.x
let yPosition = location.y - geometry[proxy.plotAreaFrame].origin.y
guard let month: String = proxy.value(atX: xPosition) else { return }
guard let measure: Double = proxy.value(atY: yPosition) else { return }
// more logic here ....
select = month
}
}
struct Measurement: Identifiable {
var id: String
var val: Double
}
如果您只想点击BarMarks
,请参阅我的其他答案: How to change the color of BarView in SwiftUI charts when we tap on it
尝试创建一个包装BarMark
并符合View
协议的自定义视图,然后为这个自定义视图添加onHover()修饰符。
或者,您可以结合使用 SwiftUI 视图和手势识别器来创建自己的图表,并使用onHover()
修饰符或HoverGesture
来检测用户何时将鼠标悬停在图表的特定区域上。
在任何情况下,您都必须创建自己的图表,这会涉及更多工作,但也会让您更好地控制图表的外观和行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.