Detect DragGesture cancelation in SwiftUI

后端 未结 1 487
庸人自扰
庸人自扰 2021-01-05 19:09

So I have a Rectangle with an added DragGesture and want to track gesture start, change and ending. The issue is when I put another finger on the Rectangle while performing

相关标签:
1条回答
  • 2021-01-05 20:14

    Thanks to @krjw for the hint with an even number of fingers

    This appears to be a problem in the Gesture framework for attempting to detect a bunch of gestures even if we didn't specify that it should be listening for them.

    As the documentation is infuriatingly sparse we can only really guess at what the intended behaviour and lifecycle here is meant to be (IMHO - this seems like a bug) - but it can be worked around.

    Define a struct method like

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

    Then combine several gestures into one to cover the bases that we didn't specify

    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
    

    There might be a better combo for simultaneously and exclusively but for my use case at least (which is for something similar to a joystick) this seems like it is doing the job

    There is also a GestureMask type that might have done the job but there is no documentation on how that works.

    0 讨论(0)
提交回复
热议问题