如何检测拖动手势期间手指何时“退出”元素边界?

问题描述 投票:0回答:1

我正在开发一个自定义按钮组件,我需要使用拖动手势来设置自定义动画的各种状态,下面是我目前所在位置的简化代码。这里的问题是与按钮关联的操作在

.onEnded
阶段执行。这意味着用户可以将手指拖动到按钮之外,释放手指后将调用操作。我想检测手指是否在按钮的范围内,以及用户是否将其拖出,不执行操作并将点击状态切换为关闭,本质上是在手指不在按钮上时取消点击。

我尝试将

GeometryReader
包裹在我的
HStack
周围,但它报告了奇怪的值(比按钮的实际大小高得多的值),并且它使按钮组件扩展到全屏宽度和高度。

    HStack {
      Text("Sample Text")
    }
    .scaleEffect(taping ? 0.9 : 1)
    .gesture(
      DragGesture(minimumDistance: 0)
        .onChanged { pressed in
          taping.toggle()
        }
        .onEnded { pressed in
          taping.toggle()
          // Execute tap action here
        }
    )
ios swift swiftui gesture
1个回答
0
投票

我能够检测手指是否在元素之外或没有使用 GeometryReader,但无法弄清楚如何强制结束拖动手势。请尝试以下代码。

使用PreferenceKey获取视图的frame:

struct ButtonPreferenceData: Equatable {
    let bounds: CGRect
}

struct ButtonPreferenceKey: PreferenceKey {
    typealias Value = ButtonPreferenceData

    static var defaultValue: ButtonPreferenceData = ButtonPreferenceData(bounds: CGRect())

    static func reduce(value: inout ButtonPreferenceData, nextValue: () -> ButtonPreferenceData) {
        value = nextValue()
    }
}

使用 GeometryReader 检查拖动位置:

HStack {
    Text("Sample Text")
        .border(Color.black, width: 1)
}
.scaleEffect(taping ? 0.9 : 1)
.background(
    GeometryReader { reader in
        let frame = reader.frame(in: .local)
        Rectangle()
            .fill(Color.clear)
            .preference(key: ButtonPreferenceKey.self, value: ButtonPreferenceData(bounds: frame))
    }
)
.onPreferenceChange(ButtonPreferenceKey.self) { value in
    bounds = value.bounds
    print("\(bounds)")
}
.gesture(
    DragGesture(minimumDistance: 0)
        .onChanged { pressed in
            if bounds.contains(pressed.location) {
                print("Inside")
            } else {
                print("Outside")
            }
            taping = true
        }
        .onEnded { _ in
            taping = false
        }
)
© www.soinside.com 2019 - 2024. All rights reserved.