SwiftUI View Overlap when integrated with Drag gesture

747 Views Asked by At

I am new to swiftUI and facing an issue when working with DragGesture functionality of view. I am trying to create a photo gallery app which have swipe functionality. Facing an issue with having a gesture view embedded in HStack with other 2 views. The 1st view of HStack get covered by drag view but the 3rd view of HStack is shown on top of Drag view. How can I make the 1st view also to be shown on top of my gesture view. The Review screen is the view where the Gesture view is created.

struct ReviewScreen: View {
    @State var swipeHorizontalDirection: SwipeHorizontalDirection = .none { didSet { print(swipeHorizontalDirection) } }
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .leading, spacing: 20)  {
                HStack(spacing: 20) {
                    Image("red_rectangle")
                        .resizable()
                        .frame(width: 12, height: 100)
                    
                    Image(uiImage: renderImage)
                        .resizable()
                    
                        .frame(width: geometry.size.width * 0.75, height: geometry.size.height * 0.55)
                        .cornerRadius(10)
                        .onSwipe { direction in
                            switch direction {
                            case .right:
                                break
                            case .left:
                                self.presentationMode.wrappedValue.dismiss()
                            default:
                                break
                            }
                        }
                    Image("green_rectangle")
                        .resizable()
                        .frame(width: 12, height: 100)
                }
                Spacer()
            }
            .padding(20)
        }
    }
}

And the Swipe modifier code is -

struct SwipeModifier: ViewModifier {
    let action: ((UISwipeGestureRecognizer.Direction) -> Void)?
    @State var offset: CGSize = .zero
    @State var startingOffsetX: CGFloat = UIScreen.main.bounds.width
    
    
    init(perform action: ((UISwipeGestureRecognizer.Direction) -> Void)? = nil) {
        self.action = action
    }
    
    func body(content: Content) -> some View {
        ZStack {
            content
                .offset(offset)
                .scaleEffect(getScaleAmount())
                .gesture(
                    DragGesture()
                        .onChanged({ value in
                            withAnimation(.spring()) {
                                offset = CGSize(width: value.translation.width, height: 0)
                            }
                        })
                        .onEnded({ value in
                            guard let action = action else {
                                return
                            }
                            withAnimation(.spring()) {
                                if value.location.x != 0,
                                   value.startLocation.x < value.location.x && offset.width > 150 {
                                    print("right call >> \(offset.width)")
                                    action(.right)
                                }
                                else if value.startLocation.x > value.location.x && offset.width < -150 {
                                    print("left call >> \(offset.width)")
                                    action(.left)
                                }
                                offset = .zero
                            }
                        })
                )
        }
    }
    

    func getScaleAmount() -> CGFloat {
        let max = UIScreen.main.bounds.width / 2
        let currentAmount = abs(offset.width)
        let percentage = currentAmount / max
        return 1.0 - min(percentage, 0.5) * 0.5
    }
}

extension View {
    public func onSwipe(perform action: ((UISwipeGestureRecognizer.Direction) -> Void)? = nil) -> some View {
        return self.modifier(SwipeModifier(perform: action))
    }
}

enter image description here

0

There are 0 best solutions below