UIView animateWithDuration is too fast
Asked Answered
R

4

7

I have used UIView animateWithDuration to increase the shapeLayer.frame.size.height in the code below, but regardless of the duration it animates very fast. A few posts that I found recommended using some delay time which I've done, but it still animates very quickly, ignoring the 5 seconds duration I set.

private let minimalHeight: CGFloat = 50.0  
private let shapeLayer = CAShapeLayer()

override func loadView() {  
super.loadView()

shapeLayer.frame = CGRect(x: 0.0, y: 0.0, width: view.bounds.width, height: minimalHeight)
shapeLayer.backgroundColor = UIColor(red: 57/255.0, green: 67/255.0, blue: 89/255.0, alpha: 1.0).CGColor
view.layer.addSublayer(shapeLayer)

  }

func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}


override func viewDidAppear(animated: Bool) {
   delay(3)    {

    UIView.animateWithDuration(5.0) {
        self.shapeLayer.frame.size.height += 400.0
        }
    }

How can I make the animation complete in 5 seconds?

Robenarobenia answered 9/3, 2016 at 8:59 Comment(0)
D
2

Maybe you should try CABasicAnimation

    let fromValue = view2.layer.bounds.height
    let toValue = view2.layer.bounds.height + 50
    CATransaction.setDisableActions(true) //Not necessary
    view2.layer.bounds.size.height = toValue
    let positionAnimation = CABasicAnimation(keyPath:"bounds.size.height")
    positionAnimation.fromValue = fromValue
    positionAnimation.toValue = toValue
    positionAnimation.duration = 1
    view2.layer.addAnimation(positionAnimation, forKey: "bounds")
Disappear answered 9/3, 2016 at 13:27 Comment(3)
thanks, it's working but I would really like to know why animateWithDuration isn't working.Robenarobenia
Because you are using animation methods working for UIViews. You are trying to animate a CALayer witch is a lower level component.Disappear
I'll really appreciate if you could take a look at this SO question for me goo.gl/iqSmQq, I've not been able to make any progress on itRobenarobenia
M
2

Try it :

override func viewDidAppear(_ animated: Bool) {
    //You should not edit directly the frame here, or the change will be committed ASAP. Frame does not act like constraints.
    // create the new frame
    var newFrame = self.shapeLayer.frame
    newFrame.size.height += 400.0

    UIView.animate(withDuration: 5.0, delay: 3.0, options: .curveEaseOut, animations: {
        //assign the new frame in the animation block
        self.shapeLayer.frame = newFrame
    }, completion: { finished in

    })
}
Moth answered 9/3, 2016 at 9:11 Comment(7)
I tried the code above but the animation is still very fastRobenarobenia
The animation is very fast or there is no animation ?Moth
Basically, in less than a second it moves from its original position to the intended position. That's why I said the animation is very fastRobenarobenia
#12958541 Maybe the solution is here.Moth
the second approach in the link is what I did at firstRobenarobenia
I also tried the edit by @bobby, but still getting the same resultRobenarobenia
@Robenarobenia can you add self.view.layoutIfNeeded() below the frame resizing line in your code?Cabral
D
2

Maybe you should try CABasicAnimation

    let fromValue = view2.layer.bounds.height
    let toValue = view2.layer.bounds.height + 50
    CATransaction.setDisableActions(true) //Not necessary
    view2.layer.bounds.size.height = toValue
    let positionAnimation = CABasicAnimation(keyPath:"bounds.size.height")
    positionAnimation.fromValue = fromValue
    positionAnimation.toValue = toValue
    positionAnimation.duration = 1
    view2.layer.addAnimation(positionAnimation, forKey: "bounds")
Disappear answered 9/3, 2016 at 13:27 Comment(3)
thanks, it's working but I would really like to know why animateWithDuration isn't working.Robenarobenia
Because you are using animation methods working for UIViews. You are trying to animate a CALayer witch is a lower level component.Disappear
I'll really appreciate if you could take a look at this SO question for me goo.gl/iqSmQq, I've not been able to make any progress on itRobenarobenia
P
0
  1. Instead of putting the change inside the animation block, making the change before the animation.

  2. Then, in the animation, only call superView.layoutIfNeeded()

It works for me, reference: How do I animate constraint changes?

Pathological answered 18/7, 2016 at 9:18 Comment(0)
S
0

In my case the problem was that somewhere else in the code animations were disabled:

[UIView setAnimationsEnabled:false];

Changing this to true solved the issue:

[UIView setAnimationsEnabled:true];

Sandbox answered 13/6, 2019 at 10:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.