繁体   English   中英

无论如何,在 SwiftUI 中是否可以检测 `BarMark` 上的悬停手势?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM