如何让动画和手势识别器协同工作? (Swift)
How to make animations and gesture recognisers work together? (Swift)
我做了一个简单的项目,带有滑动手势识别器和动画。我让我的标签移动,每 3 秒增加一个数字。每次滑动我都需要减少数量。我的手势识别器对象与标签绑定,即它仅在标签范围内有效。当 prog 在没有动画的情况下工作时,一切正常,但是当它;s 动画并且正在移动时,我的手势识别器什么都不做。如何使手势识别器与动画同时工作,即动画响应我的滑动。需要帮助。
`
@IBOutlet weak var label1: UILabel!
var number : Int = 0
var timer = Timer()
@IBAction func label1SwipeRight(_ sender: UISwipeGestureRecognizer) {
number += 1
label1.text = String(number)
}
func animate1() {
UIView.animate(withDuration: 4.0, delay: 0.0, options: .allowUserInteraction, animations: {
let num1 : CGFloat = CGFloat(arc4random_uniform(667))
let num2 : CGFloat = CGFloat(arc4random_uniform(375))
self.label1.frame.origin.y = num1
self.label1.frame.origin.x = num2
}, completion: {(bool) in
self.animate1()
print("Animation1 completed")
})
}
func timerExample() {
Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
}
@objc func updateTimer() {
label1.text = String(Int(label1.text!)! + 1)
}`
默认情况下,当动画 "in flight" 时,视图对象会阻止用户交互。您需要使用"long form" 动画方法之一,并传入选项.allowUserInteraction
。像这样:
UIView.animate(duration: 0.5,
delay: 0.0,
options: .allowUserInteraction,
animations: {
myView.alpha = 0.5
})
但是请注意,如果您要设置动画的是视图的位置,则用户将无法在视图对象移动时点击它。那是因为位置动画并没有真正随着时间的推移将对象从一个地方移动到另一个地方。它只是创造了那种外观。在幕后,对象实际上在动画开始时跳到它的最终位置。
如果您需要能够在对象移动时对它们进行 tap/drag/swipe,则您必须自己完成。您所做的是在包含整个运动范围(可能是整个屏幕)的父视图上放置一个手势识别器。然后您需要使用动画视图层的表示层,从手势识别器的坐标转换点的坐标坐标space到图层坐标space,并使用图层的hitTest方法判断该点是否在图层上。
我在 Github 上有一个名为 iOS-CAAnimation-group-demo 的项目,它做类似的事情(它沿着复杂的路径为图像视图设置动画,您可以点击图像视图暂停动画"in flight".
这是几年前的事了,所以它是用 Objective-C 写的,但至少应该有助于说明该技术。
我做了一个简单的项目,带有滑动手势识别器和动画。我让我的标签移动,每 3 秒增加一个数字。每次滑动我都需要减少数量。我的手势识别器对象与标签绑定,即它仅在标签范围内有效。当 prog 在没有动画的情况下工作时,一切正常,但是当它;s 动画并且正在移动时,我的手势识别器什么都不做。如何使手势识别器与动画同时工作,即动画响应我的滑动。需要帮助。
`
@IBOutlet weak var label1: UILabel!
var number : Int = 0
var timer = Timer()
@IBAction func label1SwipeRight(_ sender: UISwipeGestureRecognizer) {
number += 1
label1.text = String(number)
}
func animate1() {
UIView.animate(withDuration: 4.0, delay: 0.0, options: .allowUserInteraction, animations: {
let num1 : CGFloat = CGFloat(arc4random_uniform(667))
let num2 : CGFloat = CGFloat(arc4random_uniform(375))
self.label1.frame.origin.y = num1
self.label1.frame.origin.x = num2
}, completion: {(bool) in
self.animate1()
print("Animation1 completed")
})
}
func timerExample() {
Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
}
@objc func updateTimer() {
label1.text = String(Int(label1.text!)! + 1)
}`
默认情况下,当动画 "in flight" 时,视图对象会阻止用户交互。您需要使用"long form" 动画方法之一,并传入选项.allowUserInteraction
。像这样:
UIView.animate(duration: 0.5,
delay: 0.0,
options: .allowUserInteraction,
animations: {
myView.alpha = 0.5
})
但是请注意,如果您要设置动画的是视图的位置,则用户将无法在视图对象移动时点击它。那是因为位置动画并没有真正随着时间的推移将对象从一个地方移动到另一个地方。它只是创造了那种外观。在幕后,对象实际上在动画开始时跳到它的最终位置。
如果您需要能够在对象移动时对它们进行 tap/drag/swipe,则您必须自己完成。您所做的是在包含整个运动范围(可能是整个屏幕)的父视图上放置一个手势识别器。然后您需要使用动画视图层的表示层,从手势识别器的坐标转换点的坐标坐标space到图层坐标space,并使用图层的hitTest方法判断该点是否在图层上。
我在 Github 上有一个名为 iOS-CAAnimation-group-demo 的项目,它做类似的事情(它沿着复杂的路径为图像视图设置动画,您可以点击图像视图暂停动画"in flight".
这是几年前的事了,所以它是用 Objective-C 写的,但至少应该有助于说明该技术。