问题
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)
}
}
回答1:
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
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)
}
回答2:
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 :)
来源:https://stackoverflow.com/questions/61333807/how-to-display-an-image-where-the-user-taps-swiftui