Reputation: 247
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?
Upvotes: 7
Views: 2708
Reputation: 131
In my case, I was programmatically adding my animatedView
as an arranged subview of a UIStackView
so that I could load it lazily. After calling addArrangedSubview(animatedView)
, my animatedView
was laid out properly but its animation was running at 2x the requested speed (or half the duration).
I was able to resolve it by simply calling layoutIfNeeded()
on my UIStackView
after adding animatedView
to it as an arranged subview.
However, to confirm, I then removed the layoutIfNeeded()
call, which should have triggered the rapid animation again. To my surprise, it didn't bring the issue back. I was doing this in a simulator so it may just be some internal UIKit
quirk that's causing it because I can't reliably repro the issue once it goes away.
But calling layoutIfNeeded()
on a parent after you've added your animated view as its subview should fix the issue.
Upvotes: -1
Reputation: 2048
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
})
}
Upvotes: 2
Reputation: 1227
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];
Upvotes: 0
Reputation: 4491
Instead of putting the change inside the animation block, making the change before the animation.
Then, in the animation, only call superView.layoutIfNeeded()
It works for me, reference: How do I animate constraint changes?
Upvotes: 0
Reputation: 5588
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")
Upvotes: 2