gpt4 book ai didi

uiview - 无法访问 UIPanGestureRecognizer 中的对象

转载 作者:可可西里 更新时间:2023-11-01 01:43:28 26 4
gpt4 key购买 nike

我正在使用以编程方式生成的对象制作贝塞尔动画。对象的数量可能超过 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:");
}
}

.. 在 vi​​ewDidLoad 中调用函数:

    // 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. 您的 for 循环正在为 recognizer 设置委托(delegate)(这是不需要的,除非您正在做一些您没有与我们分享的特定事情)并且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)
    }
  2. panning 中,您正在实例化一个新的 panGesture:您肯定想摆脱它。手势处理程序无权创建新手势。因此,去掉以 let panGesture = ... 开头的行。

  3. 在您最初的问题中,您没有分享您正在制作的动画。如果您使用基于 block 的动画制作动画,则必须指定 UIViewAnimationOptions.AllowUserInteraction 选项。此外,如果您开始将它拖到正在动画的 View 周围,您还需要 (a) 停止该 View 的动画; (b) 根据 presentationLayer 重置 frame

    但是,现在很清楚您正在使用 CAKeyframeAnimation,在这种情况下,没有 AllowUserInteraction 机制。因此,您必须将手势识别器添加到 superview,然后遍历方 block 的帧(由它们的表示层表示,即动画中的位置)并进行测试以查看如果你得到任何点击。

  4. 这取决于您,但我发现平移手势开始识别手势有点慢(因为它区分平移和轻敲。在这种情况下,您需要响应更快的东西,我认为,所以我可能会使用带有

  5. 的长按手势识别器

所以,把所有这些放在一起,你最终会得到类似这样的东西:

var squares = [UIView]() // an array to keep track of all of the squares

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)

squares.append(square)

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

let recognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPress:");
recognizer.minimumPressDuration = 0
view.addGestureRecognizer(recognizer)
}

var viewToDrag: UIView! // which of the squares are we dragging
var viewToDragCenter: CGPoint! // what was the `center` of `viewToDrag` when we started to drag it
var originalLocation: CGPoint! // what was gesture.locationInView(gesture.view!) when we started dragging

func handleLongPress(gesture: UILongPressGestureRecognizer) {
let location = gesture.locationInView(gesture.view!)

if gesture.state == .Began {
for square in squares {
let presentationLayer = square.layer.presentationLayer() as CALayer
let frame = presentationLayer.frame
if CGRectContainsPoint(frame, location) {
viewToDrag = square
viewToDragCenter = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
viewToDrag.layer.removeAnimationForKey("animate position along path")
viewToDrag.center = viewToDragCenter
originalLocation = location
return
}
}
} else if gesture.state == .Changed {
if viewToDrag != nil {
var translation = CGPointMake(location.x - originalLocation.x, location.y - originalLocation.y)
viewToDrag.center = CGPointMake(viewToDragCenter.x + translation.x, viewToDragCenter.y + translation.y)
}
} else if gesture.state == .Ended {
viewToDrag = nil
}
}

关于uiview - 无法访问 UIPanGestureRecognizer 中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26580628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com