Search code examples
imagepositionswiftui

How to display an image where the user taps? SwiftUI


I am making a mining tapping game and I want to display a hammer wherever the user taps.

I mean, wherever the user taps the hammer image will stay on for one second.

Is there a way to do it?

My example code is below:

struct Level1: View {

@State var tapScore = 0
@State var showingMinedHammer = false

func showMinedHammer() {
    self.showingMinedHammer = true
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    self.showingMinedHammer = false
    }
}

func mine() {
    tapScore += 1
    showMinedHammer()
}

var body: some View {
     GeometryReader { geometryProxy in
        ZStack {
Image("mine1").resizable().frame(width: UIScreen.main.bounds.height * 1.4, height: UIScreen.main.bounds.height)
              .onTapGesture {
            self.mine()
            }

if self.showingMinedHammer {
                Image(systemName: "hammer.fill")
                .resizable()
                .frame(width: 30, height: 30)
            }

}
}.edgesIgnoringSafeArea(.all)
}
}

Solution

  • It just need to read location of tap and use it as position for hammer image, like below - all by SwiftUI

    Tested with Xcode 11.4 / iOS 13.4

    demo

    Here is modified only part

    @State private var location = CGPoint.zero      // < here !!
    var body: some View {
        GeometryReader { geometryProxy in
            ZStack {
                Image("mine1").resizable().frame(width: UIScreen.main.bounds.height * 1.4, height: UIScreen.main.bounds.height)
                    .gesture(DragGesture(minimumDistance: 0).onEnded { value in
                        self.location = value.location // < here !!
                        self.mine()
                    })
                if self.showingMinedHammer {
                    Image(systemName: "hammer.fill")
                        .resizable()
                        .frame(width: 30, height: 30)
                        .position(self.location)    // < here !!
                }
            }
        }.edgesIgnoringSafeArea(.all)
    }