Tap Gesture on animating UIView not working

若如初见. 提交于 2019-11-29 11:39:07

You will not be able to accomplish what you are after using a tapgesture for 1 huge reason. The tapgesture is associated with the frame of the label. The labels final frame is changed instantly when kicking off the animation and you are just watching a fake movie(animation). If you were able to touch (0,900) on the screen it would fire as normal while the animation is occuring. There is a way to do this a little bit different though. The best would be to uses touchesBegan. Here is an extension I just wrote to test my theory but could be adapted to fit your needs.For example you could use your actual subclass and access the label properties without the need for loops.

extension UIViewController{

public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    guard let touch = touches.first else{return}
    let touchLocation = touch.locationInView(self.view)

    for subs in self.view.subviews{
        guard let ourLabel = subs as? UILabel else{return}
        print(ourLabel.layer.presentationLayer())

        if ourLabel.layer.presentationLayer()!.hitTest(touchLocation) != nil{
            print("Touching")
            UIView.animateWithDuration(0.4, animations: {
                self.view.backgroundColor = UIColor.redColor()
                }, completion: {
                    finished in
                    UIView.animateWithDuration(0.4, animations: {
                        self.view.backgroundColor = UIColor.whiteColor()
                        }, completion: {
                            finished in
                    })
                })
            }
        }

    }
}

You can see that it is testing the coordinates of the CALayer.presentationLayer()..That's what I was calling the movies. To be honest, I have still not wrapped my head completely around the presentation layer and how it works.

If you want to see the animation, you need to put it in the onTap handler.

let gesture = UITapGestureRecognizer(target: self, action: "onTap:")
gesture.numberOfTapsRequired = 1
label.addGestureRecognizer(gesture)
label.userInteractionEnabled = true

label.transform = CGAffineTransformMakeTranslation(0, 0)

UIView.animateWithDuration(12, delay: 3, options: [.AllowUserInteraction], animations: { () -> Void in
      label.transform = CGAffineTransformMakeTranslation(0, 900)
      }, completion: nil)


func onTap(sender : AnyObject)
{

    print("Tapped")
}

For your tap gesture to work, you have to set the number of taps. Add this line:

tapGesture.numberOfTapsRequired = 1

(I'm assuming that tapGesture is the same one you call label.addGestureRecognizer(tapGesture) with)

Below is a more generic answer based on the answer from @agibson007 in Swift 3.

This didn't solve my issue immediately, because I had additional subviews covering my view. If you have trouble, try changing the extension type and writing print statements for touchLocation to find out when the function is firing. The description in the accepted answer explains the issue well.

extension UIViewController {

    open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard let touch = touches.first else { return }
        let touchLocation = touch.location(in: self.view)

        for subview in self.view.subviews {

            if subview.tag == VIEW_TAG_HERE && subview.layer.presentation()?.hitTest(touchLocation) != nil {

                print("[UIViewController] View Touched!")
                // Handle Action Here

            }

        }

    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!