In the code below I am trying to animate a CALayer
from the left side of the screen to the right side of the screen as the user is holding down on the screen (longPressGestureRecognizer). When the user lifts their finger, the CALayer
pauses.
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
}
I have two issues:
When i print the width of the CALayer
after the animation (when user lifts finger) its always 0. I animate the width, and its expanding, thus I do not know why it does not give me the new width of the CALayer
.
After the user lifts their finger, and then holds down again, the CALayer
disappears. I need it to remain on the screen, and create another CALayer
, I do not delete it in any way, so i do not understand why it is as well disappearing. I checked the memory the object still exists.
UPDATE to issue #2 : I believe to create another CALayer
I can't just add the layer again. I must either create a copy or create a UIView
that I can add the layer to. I still do not understand why it is disappearing though.
Basically you are trying to resize the layer when user is holding down. Here is a function that can be used to resize a given layer:
If you want origin to be pegged to the left, you will need to set the anchor of the layer first:
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
}
In your case, I am not sure where you are resuming the paused layer though. Also observe every time user taps, a new animation gets added in your handleLongPress method! and this will have unwanted effect. Ideally you need to initiate animation only for the first time, and later, just resume the paused animation you started earlier.
//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)
}
}