Search code examples
iosswiftswiftuidraggesture

How to drag an image behind an image using SwiftUI


hopefully anyone of you can help me and give me advice.

I have the task of making a photo editing application with SwiftUI. In the application there is a feature to remove the background from a person's photo (so only the object of the person), then I created a new UIImage as a layer to replace the background with an image that can be shifted (behind the photo whose background has been removed), so that it is positioned When I tried to drag the new background but I couldn't, because the photo frame that was removed from the background was blocking the new UIImage background.

this is the code i have made.

struct MaskImage: View {
  @State var currentPositions = CGPoint.init(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height/4)
  @State var currentPosition = CGPoint.init(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height/4)
  @GestureState private var isDragging = false
  
  var body: some View {
    GeometryReader { geo in
      HStack {
        VStack {
          Spacer()
          
          ZStack {

              Image("EFFECT-1") // DRAGGABLE PHOTO BACKGROUND
                .resizable()
                .frame(width: abs(geo.size.width-32), height: 375, alignment: .center)
                .position(currentPosition)
                .gesture(
                  DragGesture()
                    .onChanged { value in
                      self.currentPosition = value.location
                    }
                    .updating($isDragging) { (value, state, transaction) in // 1, 2
                      state = true
                      self.currentPosition = value.location
                    }
                )
            
              Image("SEGMENTED_IMAGE_REMOVE_BACKGROUND") // The image that will be the front
                .resizable()
                .frame(width: abs(geo.size.width - 32), height: abs(round((geo.size.width / 2) * 2.438)), alignment: .center)

          }
          
          Spacer()
        }
      }
      .background(Color.red)
    }
  }
}

Solution

  • You can disable touch interactions for the top image using allowsHitTesting:

    Image("SEGMENTED_IMAGE_REMOVE_BACKGROUND") // The image that will be the front
        .resizable()
        .frame(width: abs(geo.size.width - 32), height: abs(round((geo.size.width / 2) * 2.438)), alignment: .center)
        .allowsHitTesting(false)