斯威夫特:为啥点击手势识别器不是每次都有效?

Posted

技术标签:

【中文标题】斯威夫特:为啥点击手势识别器不是每次都有效?【英文标题】:Swift: Why does Tap Gesture Recognizer not work every time?斯威夫特:为什么点击手势识别器不是每次都有效? 【发布时间】:2020-01-08 17:23:16 【问题描述】:

我有一个奇怪的问题。我在我的子视图中添加了一个基本的点击手势识别器,但它只在它喜欢的时候才起作用。有时它适用于第二次点击,有时适用于第三次甚至更多点击。但是当我将print("whatever") 添加到手势识别器调用的函数中时,它总是在我第一次单击子视图时起作用。

我该如何解决这个问题?

在这两个例子上出现同样的问题:

子视图:

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()


                    )


             )
        
    

按钮:

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)
                
            
        
    

【问题讨论】:

您有两个不同的按钮,continueButtonconfirmGiftButton,哪一个遇到了这个问题?另外,为什么要向 UIButton 添加 TapGestureRecognizer?你只需要像使用confirmGiftButton 一样向它添加一个目标。你为什么要把你的动画包装在DispatchQueue.main.async中? @Pierce 两个对象都遇到了这个问题,而 continueButton 是子视图,这就是我添加手势识别器的原因。 @Pierce 我不小心把它放在了 DispatchQueue 中,所以我现在把它删除了。 【参考方案1】:

所以我从这两种方法中删除了DispatchQueue.main.async 并尝试了几次,似乎是问题所在,因为现在子视图手势识别器和按钮目标都可以在第一次单击时正常工作。

我认为这是因为当我单击按钮时,主线程已被使用,因此它以某种方式跳过了方法。并且在第二次或更多次点击中工作,因为那时它已经是空的。

【讨论】:

以上是关于斯威夫特:为啥点击手势识别器不是每次都有效?的主要内容,如果未能解决你的问题,请参考以下文章

转iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势) -- 不错不错

为啥滑动手势识别器在 swift 中会出错?

Swift:手势识别器无法识别的选择器发送到实例

为啥我的 watchkit 应用程序没有在“开始”状态调用我的平移手势识别器处理代码?

手势识别基于matlab GUI SIFT+SVM算法手势识别含Matlab源码 1789期

基于无线信号的手势识别研究现状调查