ios - 在 SwiftUI 中检测 DragGesture 取消

标签 ios swift swiftui gesture

所以我有一个添加了 DragGesture 的 Rectangle,并且想要跟踪手势的开始、更改和结束。问题是当我在执行手势时将另一根手指放在 Rectangle 上时,第一个手势停止调用 onChange 处理程序并且不会触发 onEnded 处理程序。
此外,处理程序不会为第二根手指触发。

但是,如果我在不移除前两个手指的情况下放置第三根手指,则该手势的处理程序开始触发(以此类推,偶数按下取消奇数)

它是一个错误吗?有没有办法检测到第一个手势被取消了?

Rectangle()
  .fill(Color.purple)
  .gesture(
    DragGesture(minimumDistance: 0, coordinateSpace: .local)
      .onChanged() { event in
        self.debugLabelText = "changed \(event)"
      }
      .onEnded() { event in
        self.debugLabelText = "ended \(event)"
      }
  )

最佳答案

感谢@krjw 提供偶数手指的提示

这似乎是手势框架中的一个问题,它试图检测一堆手势,即使我们没有指定它应该监听它们。

由于文档非常稀疏,我们只能真正猜测这里的预期行为和生命周期是什么(恕我直言——这似乎是一个错误)——但它可以解决。

定义一个结构方法,如

func onDragEnded() {
  // set state, process the last drag position we saw, etc
}

然后将几个手势合二为一,覆盖我们未指定的基础
let drag = DragGesture(minimumDistance: 0)
      .onChanged({ drag in
       // Do stuff with the drag - maybe record what the value is in case things get lost later on 
      })
      .onEnded({ drag in
        self.onDragEnded()
      })

     let hackyPinch = MagnificationGesture(minimumScaleDelta: 0.0)
      .onChanged({ delta in
        self.onDragEnded()
      })
      .onEnded({ delta in
        self.onDragEnded()
      })

    let hackyRotation = RotationGesture(minimumAngleDelta: Angle(degrees: 0.0))
      .onChanged({ delta in
        self.onDragEnded()
      })
      .onEnded({ delta in
        self.onDragEnded()
      })

    let hackyPress = LongPressGesture(minimumDuration: 0.0, maximumDistance: 0.0)
      .onChanged({ _ in
        self.onDragEnded()
      })
      .onEnded({ delta in
        self.onDragEnded()
      })

    let combinedGesture = drag
      .simultaneously(with: hackyPinch)      
      .simultaneously(with: hackyRotation)
      .exclusively(before: hackyPress)

/// The pinch and rotation may not be needed - in my case I don't but 
///   obviously this might be very dependent on what you want to achieve
simultaneously 可能有更好的组合和 exclusively但至少对于我的用例(类似于操纵杆的东西),这似乎正在完成这项工作

还有一个GestureMask类型可能已经完成了这项工作,但没有关于它是如何工作的文档。

关于ios - 在 SwiftUI 中检测 DragGesture 取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58807357/

相关文章:

xcode - 非常不寻常的 Xcode 编译行为

swift - 如何将我的按钮定位到屏幕底部?用户界面

ios - Swift 只允许选择一个单元格

swift - Firebase 数据库中的数据使用 observeSingleEvent 读取两次

iphone - iOS:ReusableCell 在重用时更改我的数据

iOS自动布局多个高度

swiftui - 列表行分隔符可见性设置不起作用?代码 13

ios - 如何在 SwiftUI 中同时移动文本并更改其值?

ios - NSInternalConsistencyException 原因 +entityForName : could not locate an NSManagedObjectModel for entity name

iphone - OpenCV.Framework 不为 armv7s 架构编译