Ios 调用ToucheSStart时,已设置动画的UIView对象跳转
我有一个UILabel对象,它正在设置动画,上下移动。我使用的是Xcode 8.3和Swift 3。用户可以平移此对象并拖动到一个位置以获取一些点。我正在使用Ios 调用ToucheSStart时,已设置动画的UIView对象跳转,ios,swift,animation,touchesbegan,Ios,Swift,Animation,Touchesbegan,我有一个UILabel对象,它正在设置动画,上下移动。我使用的是Xcode 8.3和Swift 3。用户可以平移此对象并拖动到一个位置以获取一些点。我正在使用触摸xxx手势处理平移/拖动。然而,当我轻触并立即放开它时,由于某种原因,这个物体垂直地跳到了它的位置上方,我一个星期都不明白为什么 当我启用一些调试时,我只能看到调用了touchesbeated(touchesMoved没有按预期调用,也没有touchesend,这对我来说是意外的)。如果我手动禁用对象上的动画,它将按预期工作,并且可以轻
触摸xxx
手势处理平移/拖动。然而,当我轻触并立即放开它时,由于某种原因,这个物体垂直地跳到了它的位置上方,我一个星期都不明白为什么
当我启用一些调试时,我只能看到调用了touchesbeated
(touchesMoved
没有按预期调用,也没有touchesend
,这对我来说是意外的)。如果我手动禁用对象上的动画,它将按预期工作,并且可以轻松平移对象,并且显然没有对象跳跃
以下是相关代码的摘录:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self.view)
if self.optOneLbl.layer.presentation()!.hitTest(touchLocation) != nil {
//pauseLayer(self.optOneLbl.layer) <<<<< comment #1
//optOneLbl.translatesAutoresizingMaskIntoConstraints = true <<<<< comment #2
optOneLbl.center = touchLocation
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self.view)
var sender: UILabel
if self.optOneLbl.layer.presentation()!.hitTest(touchLocation) != nil {
self.optOneLbl.center = touchLocation
sender = self.optOneLbl
}
// identify which letter was overlapped
var overlappedView : UILabel
if (sender.frame.contains(letter1.center)) {
...
}
else {
return
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
}
您可以使用UIPangestureRecognitor实现同样的功能。将平移手势添加到标签,并在平移时移动标签
@IBAction func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self.view)
yourLabel!.center = CGPoint(x: yourLabel!.center.x + translation.x, y: yourLabel!.center.y + translation.y)
gestureRecognizer.setTranslation(CGPoint.zero, in: self.view)
}
}
您可以从情节提要或在viewDidLoad中以编程方式将手势识别器添加到UILabel中
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
yourLabel.addGestureRecognizer(gestureRecognizer)
使用平移手势作为优势,您不必使用后续触摸XX方法。为了解释为什么视图会向上移动,我认为您可能也在其他地方重置了标签框。也有可能出现手势与触摸相冲突的情况。由于这两种情况在您提供的代码中都不明显,我们需要更多的代码来确认相同的情况。更改标签位置后,您需要删除/重置动画。动画不知道您更新了值,并且从一开始就试图保持在相同的byValue范围内。下面是更新动画的工作示例
import UIKit
class ViewController: UIViewController {
var optOneLbl = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
optOneLbl = UILabel(frame: CGRect(x: 20, y: 50, width: self.view.bounds.width - 40, height: 40))
optOneLbl.textAlignment = .center
optOneLbl.text = "I Will Be Moving Up and Down"
optOneLbl.textColor = .white
optOneLbl.backgroundColor = .blue
self.view.addSubview(optOneLbl)
//starts it in the beginnning with a y
fireAnimation(toY: self.view.bounds.midY*1.1)
}
func fireAnimation(toY:CGFloat) {
UIView.animate(withDuration: 12.0, delay: 0.0, options: [ .allowUserInteraction, .curveLinear, .autoreverse, .repeat ], animations: {
self.optOneLbl.center = CGPoint(x: self.optOneLbl.center.x, y:toY)
})
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self.view)
if self.optOneLbl.layer.presentation()!.hitTest(touchLocation) != nil {
//re
optOneLbl.layer.removeAllAnimations()
optOneLbl.center = touchLocation
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self.view)
var sender: UILabel
if self.optOneLbl.layer.presentation()!.hitTest(touchLocation) != nil {
self.optOneLbl.center = touchLocation
sender = self.optOneLbl
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
//restart animation after finished and change the Y if you want.
// you could change duration or whatever
fireAnimation(toY: self.view.bounds.height - optOneLbl.bounds.height)
}
}
导入UIKit
类ViewController:UIViewController{
var optOneLbl=UILabel()
重写func viewDidLoad(){
super.viewDidLoad()
//加载视图后,通常从nib执行任何其他设置。
optOneLbl=UILabel(帧:CGRect(x:20,y:50,宽度:self.view.bounds.width-40,高度:40))
optOneLbl.textAlignment=.center
optOneLbl.text=“我将上下移动”
optOneLbl.textColor=.white
optOneLbl.backgroundColor=.blue
self.view.addSubview(optOneLbl)
//从一开始就用y开始
fireAnimation(玩具:self.view.bounds.midY*1.1)
}
func fireAnimation(玩具:CGFloat){
UIView.animate(持续时间:12.0,延迟:0.0,选项:[.allowUserInteraction、.curveLinear、.autoreverse、.repeat],动画:{
self.optOneLbl.center=CGPoint(x:self.optOneLbl.center.x,y:toY)
})
}
覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
让我们先接触
让touchLocation=touch!.location(在:self.view中)
如果self.optOneLbl.layer.presentation()!.hitTest(touchLocation)!=nil{
//再
optOneLbl.layer.RemoveAllianimations()
光电中心=触摸位置
}
}
覆盖功能触摸移动(touchs:Set,带有事件:UIEvent?){
让我们先接触
让touchLocation=touch!.location(在:self.view中)
var发送方:UILabel
如果self.optOneLbl.layer.presentation()!.hitTest(touchLocation)!=nil{
self.optOneLbl.center=触摸位置
发送器=自发光二极管
}
}
覆盖函数touchesend(touchs:Set,带有事件:UIEvent?){
super.touchesend(触摸,带有:事件)
//完成后重新启动动画,并根据需要更改Y轴。
//你可以改变持续时间或其他什么
fireAnimation(玩具:self.view.bounds.height-optOneLbl.bounds.height)
}
}
触摸开始后,是否应设置项目动画。也许尝试删除它,并在拖动完成后读取。实际上,让我看看动画代码。它在重复。必须设置图层的新值。移除它。拖曳然后读动画看看这个答案也许能帮你让我know@agibson007,是的,动画正在重复。我已经编辑了我的原始文章,包括动画代码。请允许我澄清一下“您必须设置图层的新值。删除它。”?谢谢你的建议。仅供参考,我以前使用的是UIPangestureRecognitor
。但是由于在中强调的问题,我采用了当前的方法,现在有了新的挑战。哇!!非常感谢这个快速工作的代码。添加removeAllAnimations()
解决了此问题。我原以为暂停动画是在做同样的事情,但现在我知道不是这样。@Heelara很高兴它起了作用。将动画视为在真实模型之上进行的单独电影。这个过程将在将来帮助你。
import UIKit
class ViewController: UIViewController {
var optOneLbl = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
optOneLbl = UILabel(frame: CGRect(x: 20, y: 50, width: self.view.bounds.width - 40, height: 40))
optOneLbl.textAlignment = .center
optOneLbl.text = "I Will Be Moving Up and Down"
optOneLbl.textColor = .white
optOneLbl.backgroundColor = .blue
self.view.addSubview(optOneLbl)
//starts it in the beginnning with a y
fireAnimation(toY: self.view.bounds.midY*1.1)
}
func fireAnimation(toY:CGFloat) {
UIView.animate(withDuration: 12.0, delay: 0.0, options: [ .allowUserInteraction, .curveLinear, .autoreverse, .repeat ], animations: {
self.optOneLbl.center = CGPoint(x: self.optOneLbl.center.x, y:toY)
})
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self.view)
if self.optOneLbl.layer.presentation()!.hitTest(touchLocation) != nil {
//re
optOneLbl.layer.removeAllAnimations()
optOneLbl.center = touchLocation
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self.view)
var sender: UILabel
if self.optOneLbl.layer.presentation()!.hitTest(touchLocation) != nil {
self.optOneLbl.center = touchLocation
sender = self.optOneLbl
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
//restart animation after finished and change the Y if you want.
// you could change duration or whatever
fireAnimation(toY: self.view.bounds.height - optOneLbl.bounds.height)
}
}