Test Whether a Uiview Is in the Middle of Animation

Test whether a UIView is in the middle of animation

A UIView has a layer (CALayer). You can send animationKeys to it, which will give you an array of keys which identify the animations attached to the layer. I suppose that if there are any entries, the animation(s) are running. If you want to dig even deeper have a look at the CAMediaTiming protocol which CALayer adopts. It does some more information on the current animation.

Important: If you add an animation with a nil key ([layer addAnimation:animation forKey:nil]), animationKeys returns nil.

Check if UIView is currently animating

You can use the completion block in the UIView method +animateWithDuration:animations:completion: (which is a more modern alternative to beginAnimations/commitAnimations) to chain multiple animations (I'm guessing this is what you want to do?).

iOS find if a view is animating

UPDATE #1:

you need a variable in your class:

BOOL _animationFinished;

and then you can use the following way for the animation:

float newAlpha = 0.0;

//TODO:Check if the previous animation has finished
if (_animationFinished == false) return;

if(answer.alpha==0.0) {
newAlpha = 1.0;
} else if(answer.alpha==1.0) {
newAlpha = 0.0;
}

[UIView animateWithDuration:1.0f animations:^{ answer.alpha = newAlpha; _animationFinished = false; } completion:^(BOOL finished){ _animationFinished = true; }];

it must be work.


ORIGINAL

I'm always checking the subject of the animation in this case, like this:

float newAlpha = 0.0;

//TODO:Check if the previous animation has finished
if (answer.alpha > 0.f || answer.alpha < 1.f) return; // it is always good enough for me
// ...or with AND it will cause the same effect:
// if (answer.alpha > 0.f && answer.alpha < 1.f) return;

if(answer.alpha==0.0) {
newAlpha = 1.0;
} else if(answer.alpha==1.0) {
newAlpha = 0.0;
}
[UIView animateWithDuration:1.0 animations:^{
answer.alpha = newAlpha;
}];

How can I determine if an animation is currently playing in UIView?

I would use the delegate methodanimationDidStart:

Delegate Methods

animationDidStart: Called when the animation begins its active
duration.

  • (void)animationDidStart:(CAAnimation *)theAnimation Parameters theAnimation The CAAnimation instance that started animating.
    Availability Available in iOS 2.0 and later. Declared In CAAnimation.h

Alternatively, you could query thepresentationLayerand compare it to the model layer. For example:

CGPoint presentationPosition = myLayer.presentationLayer.position;
CGPoint modelPosition = myLayer.position;

BOOL animationInProgress = NO;

if (presentationPosition.x != modelPosition.x ||
presentationPosition.y != modelPosition.y)
{
animationInProgress = YES;
}

UIView center position during animation

I figured out a possible answer.

CALayer has a presentation() function

func presentation()
Returns a copy of the presentation layer object that represents the state of the layer as it currently appears onscreen.

the presentation layer has a frame property what is a CGRect and from here easy the calculate the midpoint.

Demo

Sample Image

Code

class ViewController: UIViewController {
var circle : UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let animator = UIViewPropertyAnimator(duration: 10, curve: .easeInOut)
circle = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0))
circle.layer.cornerRadius = 20.0
circle.backgroundColor = UIColor.blue
self.view.addSubview(circle)
Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true)
{
[weak self] (myTimer) -> Void in
if let movingBlueDotFrame = self?.circle.layer.presentation()?.frame
{
let blueDotOriginPoint = movingBlueDotFrame.origin
let blueDotMiddlePoint = CGPoint(x: blueDotOriginPoint.x + movingBlueDotFrame.width/2, y: blueDotOriginPoint.y + movingBlueDotFrame.height/2)
print(blueDotMiddlePoint)
if blueDotMiddlePoint == CGPoint(x:100,y:100){
print("Yeeaahh")
myTimer.invalidate()
}
}
}
animator.addAnimations {
self.circle.center = CGPoint(x: 100,y: 100)
}
animator.startAnimation()
}
}

The idea came from here UIView animation determine center during animation

If you have some simpler or nicer solution, please add below. Thanks!

Different animation duration for subviews of an UIView

You can use UIView:animateKeyframesWithDuration then use UIView:addKeyframeWithRelativeStartTime to set its start time and duration

[UIView animateKeyframesWithDuration:2 delay:0 options:0 animations:^{
[UIView addKeyframeWithRelativeStartTime:0.32 relativeDuration:0.68 animations:^{
view.frame = frame;
}];
[UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:1 animations:^{
subview.frame = frame2;
}];
} completion:^(BOOL finished) {
}];


Related Topics



Leave a reply



Submit