gpt4 book ai didi

如果鼠标移动太快,SwiftUI onHover 不会注册鼠标离开元素

转载 作者:行者123 更新时间:2023-12-03 16:31:52 24 4
gpt4 key购买 nike

我在 SwiftUI 中制作了一些自定义 slider View ,它们根据悬停状态更改外观,但是如果鼠标移出太快(这实际上是移动光标的非常合理的速度),它会保持悬停状态,直到您重新-缓慢悬停并重新离开组件。
有解决方案吗?
悬停代码非常标准:

struct RulerSlider: View {
@State var hovering = false

var body: some View {
GeometryReader { geometry in
ZStack {
// Ruler lines
if hovering {
Ruler()
}
}
.onHover { hover in
withAnimation(.easeOut(duration: 0.1)) {
self.hovering = hover
}
}
}
}
}
问题如下:
enter image description here
重现错误的示例代码:
https://gist.github.com/rdev/ea0c53448e12835b29faa11fec8e0388

最佳答案

我今天用一个空的 NSView 上的跟踪区域解决了这个问题。这是在一个半复杂且快速刷新的 GridView 中测试的,该 View 之前具有您所描绘的相同行为。大约 75 个 View 在 GIF capture in this gist 中应用了此修饰符,大多数彼此之间的边界为零。
调用站点的糖

import SwiftUI

extension View {
func whenHovered(_ mouseIsInside: @escaping (Bool) -> Void) -> some View {
modifier(MouseInsideModifier(mouseIsInside))
}
}
用空的跟踪 View 表示
struct MouseInsideModifier: ViewModifier {
let mouseIsInside: (Bool) -> Void

init(_ mouseIsInside: @escaping (Bool) -> Void) {
self.mouseIsInside = mouseIsInside
}

func body(content: Content) -> some View {
content.background(
GeometryReader { proxy in
Representable(mouseIsInside: mouseIsInside,
frame: proxy.frame(in: .global))
}
)
}

private struct Representable: NSViewRepresentable {
let mouseIsInside: (Bool) -> Void
let frame: NSRect

func makeCoordinator() -> Coordinator {
let coordinator = Coordinator()
coordinator.mouseIsInside = mouseIsInside
return coordinator
}

class Coordinator: NSResponder {
var mouseIsInside: ((Bool) -> Void)?

override func mouseEntered(with event: NSEvent) {
mouseIsInside?(true)
}

override func mouseExited(with event: NSEvent) {
mouseIsInside?(false)
}
}

func makeNSView(context: Context) -> NSView {
let view = NSView(frame: frame)

let options: NSTrackingArea.Options = [
.mouseEnteredAndExited,
.inVisibleRect,
.activeInKeyWindow
]

let trackingArea = NSTrackingArea(rect: frame,
options: options,
owner: context.coordinator,
userInfo: nil)

view.addTrackingArea(trackingArea)

return view
}

func updateNSView(_ nsView: NSView, context: Context) {}

static func dismantleNSView(_ nsView: NSView, coordinator: Coordinator) {
nsView.trackingAreas.forEach { nsView.removeTrackingArea($0) }
}
}
}

关于如果鼠标移动太快,SwiftUI onHover 不会注册鼠标离开元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65841298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com