Nawfaal Mangou
Nawfaal Mangou

Reputation: 99

I want to limit the number of taps

Each tap adds an object on my scene, but I want to add it only once and then disable the Tap gesture. I looked everywhere but none of them are working with my code. Can someone help me with this? Either limiting the tap to 1 only or disabling it. I tried adding the tap gesture as Outlet and then setting .isEnabled = false but it is still not working.

class ARScene: UIViewController, ARSCNViewDelegate, UIGestureRecognizerDelegate {

@IBOutlet weak var sceneView: ARSCNView!




var tap : UITapGestureRecognizer!

override func viewDidLoad() {
    super.viewDidLoad()
   self.sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
    let configuration = ARWorldTrackingConfiguration()

    self.sceneView.session.run(configuration)

    // Set the view's delegate
    sceneView.delegate = self

    sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]

    // Show statistics such as fps and timing information
    sceneView.showsStatistics = true

    // Create a new scene
    // let scene = SCNScene(named: "art.scnassets/ship.scn")!

    // Set the scene to the view
    //sceneView.scene = scene

    registerGestureRecognizer()



}

func registerGestureRecognizer(){
    let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
    tap.numberOfTapsRequired = 1
    sceneView.addGestureRecognizer(tap)

}



@objc func handleTap(gestureRecognizer: UIGestureRecognizer){

    //let touchLocation = gestureRecognizer.location(in: sceneView)
    let sceneLocation = gestureRecognizer.view as! ARSCNView
    let touchLocation = gestureRecognizer.location(in: sceneLocation)
    let hitResult = self.sceneView.hitTest(touchLocation, types: [.existingPlaneUsingExtent, .estimatedHorizontalPlane])

    if hitResult.count > 0 {

        guard let hitTestResult = hitResult.first else{
            return
        }


        let node = SCNNode()
        let scene = SCNScene(named: "art.scnassets/bucket/Bucket2.scn")


        let nodeArray = scene!.rootNode.childNodes

        for childNode in nodeArray{

            node.addChildNode(childNode as SCNNode)
        }


        let worldPos = hitTestResult.worldTransform
        node.scale = SCNVector3Make(0.009,0.009,0.009);
        node.position = SCNVector3(x: 0, y: worldPos.columns.3.y, z: -1.4)

        sceneView.scene.rootNode.addChildNode(node)
        tap.isEnabled = false //NOT WORKING, I want to stop tap gesture here

    }

}

Upvotes: 0

Views: 1172

Answers (2)

TheNitram
TheNitram

Reputation: 418

For you to access the gesture in the function, you need to initialize it using

    let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(gestureRecognizer:)))

Then in your handleTap method, you can this at the end of the function

    gestureRecognizer.view?.removeGestureRecognizer(gestureRecognizer)

Upvotes: 0

Iraniya Naynesh
Iraniya Naynesh

Reputation: 1165

In order to disable your tapGesture you need to have reference to the same gesture instance you assign tap to. There are two ways either create global instance so you can change its properties like Enable/Disable from anywhere Or access the variable from the action/method for that gesture.

Create the global varibale for your tap like

var tap: UITapGestureRecognizer! // global varibale

func registerGestureRecognizer(){
   tap = UITapGestureRecognizer(target: self, action: #selector(handlePanGesture(_:))) 
   tap.numberOfTapsRequired = 1
   sceneView.addGestureRecognizer(tap)
}

and then disable this in taphandle

tap.isEnabled = false // disable the gesture

Or

2 Update your handle methods to

@objc func handleTap(withTapRecognizer tapGesture: UITapGestureRecognizer) {
  ........
   tapGesture.isEnabled = false // use the instance variable and disable the gesture this will disable the gesture from which its been called
}

Upvotes: 1

Related Questions