Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在设置UIView不工作的动画时点击手势_Ios_Iphone_Swift_Uiview_Uitapgesturerecognizer - Fatal编程技术网

Ios 在设置UIView不工作的动画时点击手势

Ios 在设置UIView不工作的动画时点击手势,ios,iphone,swift,uiview,uitapgesturerecognizer,Ios,Iphone,Swift,Uiview,Uitapgesturerecognizer,我在一个UILabel上有一个点击手势,他的翻译正在被动画化。无论何时在动画期间点击标签,点击手势都不会有任何响应 这是我的密码: label.addGestureRecognizer(tapGesture) label.userInteractionEnabled = true label.transform = CGAffineTransformMakeTranslation(0, 0) UIView.animateWithDuration(12, del

我在一个UILabel上有一个点击手势,他的翻译正在被动画化。无论何时在动画期间点击标签,点击手势都不会有任何响应

这是我的密码:

    label.addGestureRecognizer(tapGesture)

    label.userInteractionEnabled = true
    label.transform = CGAffineTransformMakeTranslation(0, 0)

    UIView.animateWithDuration(12, delay: 0, options: UIViewAnimationOptions.AllowUserInteraction, animations: { () -> Void in
        label.transform = CGAffineTransformMakeTranslation(0, 900)
        }, completion: nil)
手势代码:

func setUpRecognizers() {
    tapGesture = UITapGestureRecognizer(target: self, action: "onTap:")
}
func onTap(sender : AnyObject) {
    print("Tapped")
}
有什么想法吗?谢谢:)


2021年增加的注释:
现在这非常容易,你只需覆盖hitTest。

要让你的点击手势起作用,你必须设置点击次数。添加此行:

tappostate.numberOfTapsRequired=1


(我假设
tapprocess
与您调用的
label.addgestureRecognitizer(tapprocess)
相同)

如果要查看动画,需要将其放入
onTap
处理程序中

let gesture = UITapGestureRecognizer(target: self, action: #selector(onTap(sender:))
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")
}

由于一个巨大的原因,在使用轻拍手势后,你将无法完成你的任务。点击手势与标签的框架相关联。开始动画时,标签最终帧会立即更改,而您只是在观看一部假电影(动画)。如果您能够在屏幕上触摸(0900),则在动画发生时,它将正常启动。不过,有一种方法可以做到这一点。最好的办法是使用触摸开始。这是我刚刚编写的一个扩展来测试我的理论,但是可以根据您的需要进行调整。例如,您可以使用实际的子类访问标签属性,而不需要循环

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

    }
}
扩展UIViewController{ 公共覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){ guard let touch=touch.first else{return} 让touchLocation=touch.locationInView(self.view) 对于self.view.subview中的子视图{ guard let ourLabel=subs as?UILabel else{return} 打印(ourLabel.layer.presentationLayer()) 如果我们的label.layer.presentationLayer()!.hitTest(touchLocation)!=nil{ 打印(“触摸”) UIView.animateWithDuration(0.4,动画:{ self.view.backgroundColor=UIColor.redColor() },完成日期:{ 完成于 UIView.animateWithDuration(0.4,动画:{ self.view.backgroundColor=UIColor.whiteColor() },完成日期:{ 完成于 }) }) } } } }
你可以看到它正在测试CALayer.presentationLayer()的坐标……这就是我所说的电影。老实说,我还没有完全了解表示层及其工作原理

以下是基于Swift 3中@agibson007的答案的更一般的答案

这并没有立即解决我的问题,因为我有额外的子视图覆盖我的视图。如果遇到问题,请尝试更改扩展类型并为
touchLocation
编写打印语句,以了解函数何时启动。公认答案中的描述很好地解释了这个问题

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

            }

        }

    }

}
扩展UIViewController{ 打开覆盖功能触摸开始(touchs:Set,带有事件:UIEvent?){ guard let touch=touch.first else{return} 让touchLocation=touch.location(在:self.view中) 对于self.view.subview中的子视图{ 如果subview.tag==VIEW\u tag\u HERE&&subview.layer.presentation()?.hitTest(touchLocation)!=nil{ 打印(“[UIViewController]视图!”) //在这里处理行动 } } } } 如何在移动的视图中检测触摸 就这么简单 相关提示-

不要忘记,在大多数情况下,如果动画正在运行,您当然几乎肯定会想取消它。所以,假设有一个“移动的目标”,你希望能够用手指抓住它并将其滑动到其他地方,在这种情况下,视图控制器中的代码自然会像

   func sliderTouched() {
       if alreadyMoving {
          yourPropertyAnimator?.stopAnimation(true)
          yourPropertyAnimator = nil
       }
       etc ...
   }

我被这个问题困扰了好几个小时,不明白为什么在一个动画标签上点击不起作用,这个标签在延迟3秒后滑出屏幕

说得好,关于动画的工作原理就像一部假电影的回放,3秒的延迟控制着电影的回报,然而标签的帧在动画开始时立即改变,没有延迟。因此,轻敲(取决于标签框架在其原始位置)将不起作用

我的解决方案是将3秒延迟更改为超时函数,如-

DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
   [weak self] in
   self?.hideLabel()           
}

这样可以在延迟期间保持点击工作,并允许在延迟后在hideLabel()调用中运行动画。

这可能会帮助您显示点击手势初始化代码。对于在此处搜索的任何人,请小心,带勾号的答案不起作用,这些天会使您崩溃。现在很容易做到这一点(我在答案中说明了如何做到)。不幸的是,这是一个非常过时的答案的例子。因为原来的问题作者不见了,没有人能取消勾选答案。@Fattie非常感谢!在经历了几个小时的挫折之后,这对我帮助很大。我想知道为什么苹果没有解决这个问题。@NiyogRay-对,这是苹果令人沮丧的事情之一。这是一个真正的问题,所以。。这里的“勾选”答案现在完全错了。。但问题是问这个问题的用户在五年前就消失了,从此再也没有人见过他。因此,“勾号”将永远不会被删除。如果您删除
onTap:
中的“:”,会导致应用程序崩溃<代码>:告诉点击手势,它可以将数据传递给
发送者。
。是的,我在一些代码中看到了一些我认为没有实际实现的东西,抓住了稻草。有一件事-我不知道我是否见过你调用
setUpRecognizers()
-我会记录下来以确保它已设置好(并且当你添加它时,它已设置好)。嗯,也许superview需要允许用户交互?这完全是错误的
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
   [weak self] in
   self?.hideLabel()           
}