Thursday, August 11, 2022
HomeiOS Developmentios - The right way to animate view with velocity by DragGesture...

ios – The right way to animate view with velocity by DragGesture in SwiftUI?


Subject: I’ve DragGesture on my View and I need to change offset of the View by velocity worth from DragGesture.

Particulars: I made customized sheet view and bind DragGesture to it. When consumer swipe down on the view it takes offset worth from gesture worth.translation.top. If swipe gesture is quick sufficient – view dissapear from display screen by slide down animation.

Downside: Animation of disappearing has static velocity worth, however customers swipe will be extra quicker or slower. Because of this it appears to be like like impediment – view begin shifting with velocity of drag gesture, however after gesture ended it change velocity to worth from animation.

Code of customized sheet view:

@State var offset = 0
@State var lastDragPosition: DragGesture.Worth?

VStack {
  Textual content("Sheet")
}
.body(maxWidth: .infinity, maxHeight: .infinity)
.offset(y: offset)
.gesture(
    DragGesture()
        .onChanged(onDragChanged(worth:))
        .onEnded(onDragEnded(worth:))
)
.ignoresSafeArea()

On view drag modified:

func onDragChanged(worth: DragGesture.Worth) {
    if worth.translation.top > 0 {
        // Transfer view down by finger dragging
        offset = worth.translation.top
    }

    // Save final place for calculating velocity of gesture
    lastDragPosition = worth
}

On view drag ended:

func onDragEnded(worth: DragGesture.Worth) {
    let timeDiff = worth.time.timeIntervalSince(lastDragPosition!.time)
    let velocity: CGFloat = .init(
        worth.translation.top - lastDragPosition!.translation.top
    ) / CGFloat(timeDiff)

    // If velocity of drag gesture excessive sufficient...
    if velocity > 300 {
        // ...animate it to vanish
        withAnimation(.interactiveSpring(
            response: 0.27, // This worth is tough coded!
            dampingFraction: 0.78,
            blendDuration: 0.25
        )) {
            offset = 800
        }

        return
    } else {
        // Else return view offset to preliminary state (prime of the display screen)
        withAnimation(.easeOut(length: 0.28)) {
            offset = 0
        }
    }
}

I consider it’s some type of math subject. However possibly there may be SwiftUI native answer?

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments