swiftPunk
swiftPunk

Reputation: 1

How can I transfer DragGesture to separate function in SwiftUI?

I have simple View which has 2 DragGesture, first one updating and second one onEnded, I want make my body cleaner and i want transfer those functions how we can do that? I think those are kind of clouser functions.

        struct ContentView: View {
        
        @State private var location: CGSize = CGSize()
        @GestureState private var translation: CGSize = CGSize()
    
        var body: some View {
            Circle()
                .fill()
                .frame(width: 100, height: 100, alignment: .center)
                .position(x: location.width + translation.width + 100, y: location.height + translation.height + 100)
                .gesture(
                    DragGesture()
                        
                        // transfer to updatingFunction
                        .updating($translation) { value, state, _ in
                            state = value.translation
                        }
                        
                        
                        // transfer to onEndedFunction
                       .onEnded { value in onEndedFunction(value: value)}
                    
                )
            
            
            
        }
        
        func updatingFunction() {
            
        }
        
    func onEndedFunction(value: DragGesture.Value) {
        
        location = CGSize(width: location.width + value.translation.width, height: location.height + value.translation.height)
        
    }
        
        
    }

Upvotes: 1

Views: 345

Answers (2)

Raja Kishan
Raja Kishan

Reputation: 18914

You can use inout for passing state.

struct ContentViewGesture: View {
    @State private var location: CGSize = CGSize()
    @GestureState private var translation: CGSize = CGSize()
    
    var body: some View {
        Circle()
            .fill()
            .frame(width: 100, height: 100, alignment: .center)
            .position(x: location.width + translation.width + 100, y: location.height + translation.height + 100)
            .gesture(
                DragGesture()
                    // transfer to updatingFunction
                    .updating($translation) { value, state, _ in
                        updatingFunction(value: value, state: &state) //<<-- Here
                    }
                    
                    // transfer to onEndedFunction
                    .onEnded { value in onEndedFunction(value: value)}
                
            )
    }
    
    func updatingFunction(value: DragGesture.Value, state: inout CGSize) { //<<-- Here
        state = value.translation
    }
    
    func onEndedFunction(value: DragGesture.Value) {
        location = CGSize(width: location.width + value.translation.width, height: location.height + value.translation.height)
    }
}

Upvotes: 1

Asperi
Asperi

Reputation: 257711

It does not look much reasonable, instead I would recommend to separate entire gesture (if you look for code simplification, readability, etc.)

Here is possible variant:

struct ContentView: View {
    
    @State private var location: CGSize = CGSize()
    @GestureState private var translation: CGSize = CGSize()
    
    private var dragGesture: some Gesture {
        DragGesture()
            .updating($translation) { value, state, _ in
                state = value.translation
            }
            .onEnded { value in
                location = CGSize(width: location.width + value.translation.width, height: location.height + value.translation.height)
            }
    }
    
    var body: some View {
        Circle()
            .fill()
            .frame(width: 100, height: 100, alignment: .center)
            .position(x: location.width + translation.width + 100, y: location.height + translation.height + 100)
            .gesture(dragGesture)
    }
}

Upvotes: 1

Related Questions