无法访问UIPanGestureRecognizer中的对象

时间:2014-10-27 03:06:34

标签: uiview swift uigesturerecognizer

我正在用编程生成的对象做一个bezier动画。对象的数量可能大于100.这些对象也会对触摸做出响应。

动画效果很好。现在我想让一些对象可以拖动。

但是,我无法访问UIPanGestureRecognizer函数中的各个对象。我假设我在做类/子类调用时做错了什么,但是不能想到它..

我研究的教程为屏幕上的每个动画对象都有IBOutlets或专用的类变量。我确实有很多在FOR循环中生成的对象..

你建议采用什么方法?

func panning(pan: UIPanGestureRecognizer) {

    self.view.bringSubviewToFront(pan.view!)
    var translation  = pan.translationInView(self.view)

    pan.view.center = CGPointMake(pan.view.center.x + translation.x, pan.view.center.y + translation.y)

    pan.setTranslation(CGPointZero, inView: self.view)


        let panGesture = UIPanGestureRecognizer(target: self, action: "panning:");
                }
}

..在viewDidLoad中调用函数:

    // loop from 0 to 50
    for i in 0...50 {

        // create a square object
        let square = UIView()
        square.frame = CGRect(x: 55, y: 300, width: 40, height: 40)
        square.backgroundColor = UIColor.redColor()
        self.view.addSubview(square)


        let recognizer = UIPanGestureRecognizer(target: self, action: "panning:");
        recognizer.delegate = self;
        square.addGestureRecognizer(recognizer)
        panGesture.delegate = self;

感谢Rob的反馈,这是一个更新版本:

我真的不知道如何将AllowUserInteraction添加到CAKeyframeAnimation(Rob的回答3a),因为它没有"选项"田地(我是菜鸟)。

停止正在移动的对象的动画(Rob的回答3b)完全没有我。但它在这里肯定是必要的。

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    srand48(Int(NSDate().timeIntervalSince1970))

    // loop from 0 to 5
    for i in 0...5 {

        // create a square
        let square = UIView()
        square.frame = CGRect(x: 55, y: 300, width: 40, height: 40)
        square.backgroundColor = UIColor.redColor()

        self.view.addSubview(square)
        //square.userInteractionEnabled = true;


        let recognizer = UIPanGestureRecognizer(target: self, action: "panning:");
        square.addGestureRecognizer(recognizer)



        // randomly create a value between 0.0 and 150.0
        let randomYOffset = CGFloat( drand48() * 150)

        // for every y-value on the bezier curve
        // add our random y offset so that each individual animation
        // will appear at a different y-position
        let path = UIBezierPath()
        path.moveToPoint(CGPoint(x: -16,y: 239 + randomYOffset))
        path.addCurveToPoint(CGPoint(x: 375, y: 239 + randomYOffset), controlPoint1: CGPoint(x: 136, y: 373 + randomYOffset), controlPoint2: CGPoint(x: 178, y: 110 + randomYOffset))

        // create the animation
        let anim = CAKeyframeAnimation(keyPath: "position")
        anim.path = path.CGPath
        anim.rotationMode = kCAAnimationRotateAuto
        anim.repeatCount = Float.infinity
        //anim.duration = 5.0

        // each square will take between 4.0 and 8.0 seconds
        // to complete one animation loop
        anim.duration = 4.0 + 3 * drand48()

        // stagger each animation by a random value
        // `290` was chosen simply by experimentation
        anim.timeOffset = 290 * drand48()


        // add the animation 
        square.layer.addAnimation(anim, forKey: "animate position along path")
    }
}


func panning(pan: UIPanGestureRecognizer) {

    if pan.state == .Began {
        println("pan began")
        self.view.bringSubviewToFront(pan.view!)

    } else if pan.state == .Changed {

        println("pan state changed")

        var translation  = pan.translationInView(self.view)

        pan.view?.center = CGPointMake(pan.view!.center.x + translation.x, pan.view!.center.y + translation.y)

        pan.setTranslation(CGPointZero, inView: self.view)

        println("translation")

    }
}

1 个答案:

答案 0 :(得分:2)

有两件事突然袭来我:

  1. 您的for循环正在设置recognizer的代表(除非您正在做某些您尚未与我们分享的内容)并且{{ 1}}(应删除它,因为panGesture不是您在此panGesture循环中设置的变量,并且似乎完全不相关)。因此它将是:

    for
  2. for i in 0...50 { let square = UIView() square.frame = CGRect(x: 55, y: 300, width: 40, height: 40) square.backgroundColor = UIColor.redColor() self.view.addSubview(square) let recognizer = UIPanGestureRecognizer(target: self, action: "panning:"); square.addGestureRecognizer(recognizer) } 中,您正在实例化一个新的panning:您肯定想要摆脱它。手势处理程序没有业务创建新手势。所以摆脱以panGesture开头的行。

  3. 在您的原始问题中,您还没有分享您正在做的动画。如果您使用基于块的动画进行动画制作,则必须指定let panGesture = ...选项。此外,如果您开始在正在设置动画的视图中拖动它,您还希望(a)停止该视图的动画; (b)根据UIViewAnimationOptions.AllowUserInteraction重置frame

    但是,现在很清楚你正在使用presentationLayer,在这种情况下,没有CAKeyframeAnimation机制。所以,相反,你必须将手势识别器添加到AllowUserInteraction,然后迭代正方形的帧(由它们的表示层表示,即动画中间的位置)并测试你是否得到任何点击。

  4. 这取决于你,但我发现平移手势开始识别手势有点慢(因为它区分平底锅和水龙头。在这种情况下,你想要一些东西反应灵敏,反应灵巧,所以我可能会使用带有

  5. 的长按手势识别器

    所以,把它们拉到一起,你最终得到的结果是:

    superview