Search code examples
iosswiftxcodeuigesturerecognizeruitapgesturerecognizer

Swift: Why does Tap Gesture Recognizer not work every time?


I have weird problem. I have a basic tap gesture recognizer added to my subview, but it works only when it likes to. Sometimes it works on second click, sometimes on the third or even more clicks. But when I added print("whatever") to the function, which is called by the gesture recognizer, it always works on the first time I click the subview.

How do I fix this?

On these two examples occur the same problem:

SubView:

let getGiftGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.getGift))
self.continueButton.addGestureRecognizer(getGiftGestureRecognizer)
        DispatchQueue.main.async {
            self.coverAnyUIElement(element: self.successView)
            let gift = SCNNode()
             gift.geometry = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)

             //nahodne vygenerovat geometry, nebo barvu
             let ownedGeometries = UserDefaults.standard.array(forKey: "ownedGeometries")
             let ownedColors = UserDefaults.standard.array(forKey: "ownedColors")
             let notOwnedGeometriesCount = geometriesCount - ownedGeometries!.count
             let notOwnedColorsCount = colorsCount - ownedColors!.count

             if notOwnedGeometriesCount == 0{
                 //mam vsechny geometrie
                 //vygeneruju barvu

             }else if notOwnedColorsCount == 0{
                 //mam vsechny barvy
                 //vygeneruju geometrii
             }else if(notOwnedGeometriesCount == 0 && notOwnedColorsCount == 0){
                 //mam uplne vsechno

             }else{
                 //vygeneruj cokoliv
                 let random = Int.random(in: 0...10)
                 if random <= 3{

                     //vygeneruj geometrii
                 }else{
                     //vygeneruj barvu
                 }
             }
             print(self.generateColor())
             print(self.generateGeometry())



            self.chest.opacity = 1
             self.chest.position.y = -1.8
             self.world.addChildNode(self.chest)
             let viko = self.chest.childNode(withName: "viko", recursively: false)
             self.chest.addChildNode(gift)

            print("VLAKNO1: \(Thread.isMainThread)")
             viko?.runAction(SCNAction.rotateBy(x: 0, y: 0, z: -90/(180/CGFloat.pi), duration: 1),completionHandler: {
                print("VLAKNO2: \(Thread.isMainThread)")

                    let pohyb = SCNAction.move(by: SCNVector3(0,4,0), duration: 1)
                    gift.runAction(pohyb,completionHandler: {
                       print("VLAKNO3: \(Thread.isMainThread)")

                            self.showConfirmGiftButton()


                    })


             })
        }
    }

Button:

confirmGiftButton.addTarget(self, action: #selector(acceptedGift), for: .touchUpInside)
@objc func acceptedGift(){
        DispatchQueue.main.async {
            UIButton.animate(withDuration: 0.2, animations: {
                self.confirmGiftButton.alpha = 0.9
            }) { (_) in
                UIButton.animate(withDuration: 0.2, animations: {
                    self.confirmGiftButton.alpha = 1
                }) { (_) in

                    //print("VLAKNO1: \(Thread.isMainThread)")
                    self.chest.runAction(SCNAction.fadeOut(duration: 0.5),completionHandler: {
                       // print("Vlakno: \(Thread.isMainThread)")
                        self.chest.removeFromParentNode()
                        self.moveToMenu()
                    })
                    //print("VLAKNO2: \(Thread.isMainThread)")
                    self.coverAnyUIElement(element: self.confirmGiftButton)
                }
            }
        }
    }

Solution

  • So I removed the DispatchQueue.main.async from both methods and tried it for a few times and it seems like it was the problem, because now both the subview gesture recognizer and button target works on first click correctly.

    I think that it was caused because when I clicked on the button, the Main thread was already used so it somehow skipped the methods. And worked in the second or more clicks, because in that time it was already empty.