我正在用编程生成的对象做一个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")
}
}
答案 0 :(得分:2)
有两件事突然袭来我:
您的for
循环正在设置recognizer
的代表(除非您正在做某些您尚未与我们分享的内容)并且{{ 1}}(应删除它,因为panGesture
不是您在此panGesture
循环中设置的变量,并且似乎完全不相关)。因此它将是:
for
在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
开头的行。
在您的原始问题中,您还没有分享您正在做的动画。如果您使用基于块的动画进行动画制作,则必须指定let panGesture = ...
选项。此外,如果您开始在正在设置动画的视图中拖动它,您还希望(a)停止该视图的动画; (b)根据UIViewAnimationOptions.AllowUserInteraction
重置frame
。
但是,现在很清楚你正在使用presentationLayer
,在这种情况下,没有CAKeyframeAnimation
机制。所以,相反,你必须将手势识别器添加到AllowUserInteraction
,然后迭代正方形的帧(由它们的表示层表示,即动画中间的位置)并测试你是否得到任何点击。
这取决于你,但我发现平移手势开始识别手势有点慢(因为它区分平底锅和水龙头。在这种情况下,你想要一些东西反应灵敏,反应灵巧,所以我可能会使用带有
所以,把它们拉到一起,你最终得到的结果是:
superview