👔.draggable()

SwiftUIGesturesDrag ⟩ .draggable()

import SwiftUI

// 👔 Draggable
struct Draggable: ViewModifier {
    
    // 🔸 此變數目前沒什麼用,但在其他狀況下,也許可派上用場。
    @State var isDragging = false
    
    // 🔸 拖曳時,offset 會隨時更新,但 dragOffset 保持不變。
    //    沒拖曳時,兩者是一樣的。
    @State private var offset = CGSize.zero        // current offset
    @State private var dragOffset = CGSize.zero    // prev accumulative offset
    
    // ⭐️ optional event handlers
    typealias OffsetHandler = (CGSize) -> Void
    var onChanged: OffsetHandler?
    var onEnded  : OffsetHandler?
    
    func body(content: Content) -> some View {
        content
            .offset(offset)        // ⭐️ apply offset
            .gesture(
                DragGesture()
                    .onChanged { value in
                        isDragging = true
                        // update offset
                        offset = dragOffset + value.translation
                        // event handler
                        onChanged?(offset)
                    }
                    .onEnded { value in
                        isDragging = false
                        // update offset
                        offset = dragOffset + value.translation
                        // ⭐️ save accumulative offset
                        dragOffset = offset
                        // event handler
                        onEnded?(offset)
                    }
            )
    }
}

// 🌀 View+ .draggable()
extension View {
    /// `view.draggable(onChanged:onEnded:)`
    func draggable(
        onChanged: Draggable.OffsetHandler? = nil, 
        onEnded  : Draggable.OffsetHandler? = nil
    ) -> some View {
        modifier(Draggable(onChanged: onChanged, onEnded: onEnded))
    }
}

Last updated

Was this helpful?