3

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)
}
}
I Kaya
  • 417
  • 5
  • 22
  • 1
    Does this answer your question? [How to detect a tap gesture location in SwiftUI?](https://stackoverflow.com/questions/56513942/how-to-detect-a-tap-gesture-location-in-swiftui) – Luke Morse Apr 20 '20 at 23:47
  • I feel like it should be, but I am a newbie so it's hard for me to read others' code and implement it into mine. Thanks, though! – I Kaya Apr 20 '20 at 23:56

2 Answers2

6

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)
}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Asperi
  • 228,894
  • 20
  • 464
  • 690
1

To get the location of where you tapped, you can do something like this:

import SwiftUI

struct ContentView: View {

@State var points:[CGPoint] = [CGPoint(x:0,y:0), CGPoint(x:50,y:50)]

var body: some View {

    ZStack{
        GetTapLocation {
           // tappedCallback
           location in
            self.points.append(location)
            print(self.points)
        }
    }
}
}


struct GetTapLocation:UIViewRepresentable {
var tappedCallback: ((CGPoint) -> Void)

func makeUIView(context: UIViewRepresentableContext<GetTapLocation>) -> UIView {
    let v = UIView(frame: .zero)
    let gesture = UITapGestureRecognizer(target: context.coordinator,
                                         action: #selector(Coordinator.tapped))
    v.addGestureRecognizer(gesture)
    return v
}

class Coordinator: NSObject {
    var tappedCallback: ((CGPoint) -> Void)
    init(tappedCallback: @escaping ((CGPoint) -> Void)) {
        self.tappedCallback = tappedCallback
    }
    @objc func tapped(gesture:UITapGestureRecognizer) {
        let point = gesture.location(in: gesture.view)
        self.tappedCallback(point)
    }
}

func makeCoordinator() -> GetTapLocation.Coordinator {
    return Coordinator(tappedCallback:self.tappedCallback)
}

func updateUIView(_ uiView: UIView,
                   context: UIViewRepresentableContext<GetTapLocation>) {
}

}

There has to be a simpler implementation, but until then you can get the location where you tapped. I hope that helps :)

Arturo
  • 3,254
  • 2
  • 22
  • 61
  • Thanks, but the image stay stable, I want it to be displayed where the user taps. – I Kaya Apr 21 '20 at 00:33
  • 1
    Then you can use my last example, when you tap on the image, the image stays stable on the same place, replacing it for the one you define. Or what do you mean where the user taps? – Arturo Apr 21 '20 at 00:35
  • But I do not want to tap on the hammer. At first the hammer is not visible, when there is a tap on the screen, the hammer should appear where it was tapped. – I Kaya Apr 21 '20 at 00:38
  • 1
    I updated my answer, with the first code, you can click anywhere on the screen and the location of the tap will be stored in the variable points. I hope it helps – Arturo Apr 21 '20 at 01:35