Flashing issue with the view while dragging in SwiftUI

65 Views Asked by At

I am planning to implement dragging of the entire view by dragging the Image view, but there is a flickering issue during the process. If I move the gesture code to the ZStack, the flickering disappears, but I need the operation to be limited to the Image only.

import SwiftUI
struct MyGestureView: View {
    var x: CGFloat = 200
    var y: CGFloat = 200
    @GestureState var dragGesture = CGSize.zero
    @State var startPosition = CGSize.zero
    var body: some View {
        ZStack {
            Rectangle()
                .fill(Color.red)
                .stroke(Color.white, lineWidth: 0.8)
                .frame(width: 180, height: 50)
                .cornerRadius(10)
                .contentShape(Rectangle())
            Text("hello").frame(width: 180, height: 50)
                .foregroundColor(.white)
            Image(systemName: "gobackward")
                .foregroundColor(.white)
                .background(.gray)
                .clipShape(Circle())
                .offset(x: 90, y: 25)
                .gesture(DragGesture().updating($dragGesture, body: {
                    value, state, _ in
                    state = value.translation
                    print(dragGesture)
                }).onEnded { value in
                    startPosition.width = startPosition.width + value.translation.width
                    startPosition.height = startPosition.height + value.translation.height
                })
        }
        .position(x: x, y: y)
        .offset(x: startPosition.width + dragGesture.width, y: startPosition.height + dragGesture.height)
    }
}

#Preview {
    MyGestureView()
}

If I move the gesture code to the ZStack, the flickering disappears, but I need the operation to be limited to the Image only.

1

There are 1 best solutions below

0
Jayant Badlani On BEST ANSWER

Here's how you can implement dragging of the entire view by dragging the Image without flickering, limiting the operation to the Image only, without moving the gesture code to the ZStack. I hope this solves your query.

enter image description here

import SwiftUI

struct MyGestureView: View {
    
    @State private var startPosition: CGSize = .zero
    @State private var currentPosition: CGSize = .zero
    @GestureState private var dragState: CGSize = .zero
    
    var body: some View {
        let dragGesture = DragGesture()
            .onChanged { value in
                self.currentPosition = CGSize(
                    width: self.startPosition.width + value.translation.width,
                    height: self.startPosition.height + value.translation.height
                )
            }
            .onEnded { value in
                self.startPosition = self.currentPosition
            }
        
        ZStack {
            Rectangle()
                .fill(Color.red)
                .stroke(Color.white, lineWidth: 0.8)
                .frame(width: 180, height: 50)
                .cornerRadius(10)
                .offset(currentPosition)
            
            Text("hello")
                .frame(width: 180, height: 50)
                .foregroundColor(.white)
                .offset(currentPosition)
            
            Image(systemName: "gobackward")
                .foregroundColor(.white)
                .background(Color.gray)
                .clipShape(Circle())
                .offset(x: 90, y: 25)
                .offset(currentPosition)
                .gesture(dragGesture)
        }
        .position(x: 200, y: 200)
    }
}


#Preview {
    MyGestureView()
}