- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用以编程方式生成的对象制作贝塞尔动画。对象的数量可能超过 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")
}
}
最佳答案
我突然想到两件事:
您的 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)
}
在 panning
中,您正在实例化一个新的 panGesture
:您肯定想摆脱它。手势处理程序无权创建新手势。因此,去掉以 let panGesture = ...
开头的行。
在您最初的问题中,您没有分享您正在制作的动画。如果您使用基于 block 的动画制作动画,则必须指定 UIViewAnimationOptions.AllowUserInteraction
选项。此外,如果您开始将它拖到正在动画的 View 周围,您还需要 (a) 停止该 View 的动画; (b) 根据 presentationLayer
重置 frame
。
但是,现在很清楚您正在使用 CAKeyframeAnimation
,在这种情况下,没有 AllowUserInteraction
机制。因此,您必须将手势识别器添加到 superview
,然后遍历方 block 的帧(由它们的表示层表示,即动画中的位置)并进行测试以查看如果你得到任何点击。
这取决于您,但我发现平移手势开始识别手势有点慢(因为它区分平移和轻敲。在这种情况下,您需要响应更快的东西,我认为,所以我可能会使用带有
所以,把所有这些放在一起,你最终会得到类似这样的东西:
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/
UIGestureRecognizer 的文档引用重置函数。 但是,在 UIPanGestureRecognizer(UIGestureRecognizer 的子级)上调用 reset() 会生成此错
我有一个 UIPanGestureRecognizer,它根据我的喜好检测了太多次。我需要一个计数器并计算 3 个已完成的手势。每次我用手指平移识别器位置时,它都会触发 3 到 4 次。甚至触发了5个
我正在使用 UIPanGestureRecogniser实现拖放。当拖动开始时,我需要识别被拖动的对象。但是对象相对较小。如果用户没有在对象的中心点击对象,它就不会被拖动。 问题是当手势处理程序第一次
我正在尝试使用UIPanGestureRecognizer实现页面翻转动画。这是代码: - (void)handlePan:(UIPanGestureRecognizer *)recognizer {
我有一个 UIView 子类,我在其中添加了一个 UIPanGestureRocognizer: _panGestureRecognizer = [[UIPanGestureRecognizer al
我试图使用 UIPanGestureRecognizer 来移动我的对象,但我似乎无法让它顺利移动。当我朝一个特定的方向移动并转向相反的方向时,它不会立即使用react。我认为该值可能有问题,因为它在
我正在尝试实现 View 的拖动,当拖动停止时, View 滑到顶部并消失。我可以使用 UIPanGestureRecognizer 很好地拖动 View 。但在那之后,我用动画让它滑出。问题是在拖动
我在touchesEnded方法中调用了一个名为addProjectile的方法。 addProjectile接收touchesEnded方法接收的触摸的NSSet。为简单起见,我仅将相关代码发布到我
我遇到了 UIPanGestureRecognizer 的问题。假设我使用不同的标签动态添加 10 个按钮,当我添加第一个按钮时,尝试将其拖动到其他位置,然后它就可以正常工作。然后,如果我添加其他按钮
我有一个基类,它处理单元格的一些基本动画。在我的子类中,我已经覆盖了识别器目标并想做一些其他事情,但翻译始终是 0 因为我在基类中调用翻译被重置为 .zero . 有没有办法让我的基类执行基本动画并使
我正在使用 UIPanGestureRecognizer 将图像拖出 UICollectionViewCell,然后查看它是否与屏幕上其他位置的另一个图像发生碰撞。为此,我需要能够匹配他们的翻译坐标。
我创建了一个UIPanGestureRecognizer,但问题是当我将 View 向右滑动时, View 会向左移动。 当我向左滑动 View 时,它会向右滑动。为什么? let panGestur
我正在开发一个类似于 Tinder 中的卡片 View 。当卡片X原点大于我声明的值时,它会移出屏幕。否则,它会再次粘在中心。我正在 UIPanGestureRecognizer 函数中执行所有这些操
我有一个 UIPanGestureRecognizer 附加到父 View ,带有各种 CCSprite 我想在平移时在父 View 中移动。使用 [gesture locationOfTouch:i
使用 UIPanGestureRecognizer 我们正在移动 UICollectionView 中的单元格 当我们开始拖动时 UIGestureRecognizerStateBegan 被调用。但
我有 6 个 UIImageView,每个都连接到 UIPanGestureRecognizer,它们都连接到相同的方法。方法是: - (IBAction)handlePan:(UIPanGestur
我是 swift 和 xcode 的新手。使用 xcode 10 并尝试制作一个类似应用程序的嗡嗡声,我需要在 View 中移动多个图像。我发现了很多关于 UIPanGestureRecognizer
我有一个侧面板,其中有一个 UIImageView,我在其中附加了一个 UIPanGestureRecognizer,以便您可以推/拉侧边栏。效果很好。 问题是我有一些按钮有时会出现在侧边栏下方。如果
本质上,我想做的是移动 View 以跟随用户的平移。只要使用相同的平移对象,这种方法就可以正常工作。当用户释放并启动另一个平移时,问题就出现了。 根据文档,translationInView 中的值是
我正在将 UIPanGestureRecognizer 添加到我的 View Controller 中的一个自定义 View 。 我还使用 MFSideMenu 作为滑动菜单,在其框架中将 UIPan
我是一名优秀的程序员,十分优秀!