斯威夫特:动画CALayer



在下面的代码中,当用户按住屏幕时,我试图从屏幕左侧向屏幕右侧设置CALayer的动画(longPressGestureRecognizer)。当用户抬起手指时,CALayer暂停。

var l = CALayer()
var holdGesture = UILongPressGestureRecognizer()
let animation = CABasicAnimation(keyPath: "bounds.size.width")
override func viewDidLoad() {
    super.viewDidLoad()
    setUpView()
}
func setUpView(){
    l.frame = CGRect(x: 0, y: 0, width: 0, height: 10)
    l.backgroundColor = UIColor.redColor().CGColor
    self.view.addGestureRecognizer(holdGesture)
    holdGesture.addTarget(self, action:"handleLongPress:")
}
func handleLongPress(sender : UILongPressGestureRecognizer){
    if(sender.state == .Began) { //User is holding down on screen
        print("Long Press Began")
        animation.fromValue = 0
        animation.toValue = self.view.bounds.maxX * 2
        animation.duration = 30
        self.view.layer.addSublayer(l)
        l.addAnimation(animation, forKey: "bounds.size.width")
    }
    else { //User lifted Finger
        print("Long press ended")
        print("l width: (l.bounds.size.width)")
        pauseLayer(l)
    }
}
func pauseLayer(layer : CALayer){
    var pausedTime : CFTimeInterval = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
    layer.speed = 0.0
    layer.timeOffset = pausedTime
}

我有两个问题:

  1. 当我在动画之后打印CALayer的宽度时(当用户抬起手指时),它总是0。我设置了宽度的动画,并且它正在扩展,因此我不知道为什么它没有给我CALayer的新宽度。

  2. 在用户抬起他们的手指,然后再次按住之后,CALayer消失。我需要它留在屏幕上,并创建另一个CALayer,我不会以任何方式删除它,所以我不明白为什么它也会消失。我检查了内存,这个物体仍然存在。

更新问题#2:我相信要创建另一个CALayer,我不能再添加一层。我必须创建一个副本或创建一个UIView,以便添加图层。但我仍然不明白它为什么会消失。

基本上,当用户按住时,您正在尝试调整层的大小。下面是一个可以用来调整给定图层大小的函数:

如果你想把原点固定在左边,你需要先设置图层的锚点:

layer.anchorPoint = CGPointMake(0.0, 1);
func resizeLayer(layer:CALayer, newSize: CGSize) {
    let oldBounds = layer.bounds;
    var newBounds = oldBounds;
    newBounds.size = size;

    //Ensure at the end of animation, you have proper bounds
    layer.bounds = newBounds
    let boundsAnimation = CABasicAnimation(keyPath: "bounds")
    positionAnimation.fromValue = NSValue(CGRect: oldBounds)
    positionAnimation.toValue = NSValue(CGRect: newBounds)
    positionAnimation.duration = 30
} 

在你的情况下,我不确定你在哪里恢复暂停的图层。还要注意,每次用户点击时,都会在handleLongPress方法中添加一个新的动画!并且这将产生不希望的效果。理想情况下,只需要第一次启动动画,以后只需恢复先前启动的暂停动画即可。

//Flag that holds if the animation already started..
var animationStarted = false
func handleLongPress(sender : UILongPressGestureRecognizer){
  //User is holding down on screen
  if(sender.state == .Began){
    if(animationStarted == false){
      let targetBounds =  CalculateTargetBounds() //Implement this to your need
      resizeLayer(layer, targetBounds)
      animationStarted = true
    }else {
      resumeLayer(layer)
    }
  }else {
    pauseLayer(layer)
  }
}

最新更新