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 thepresentationLayer
and 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
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
Convert an iOS Objective C Object to a JSON String
Uipangesturerecognizer - Only Vertical or Horizontal
Usage of Protocols as Array Types and Function Parameters in Swift
Autolayout: Add Constraint to Superview and Not Top Layout Guide
Upload Image from iPhone to the Server Folder
Wkwebview in Interface Builder
Cocoa-Touch: How to See If Two Nsdates Are in the Same Day
Uitableview Checkmarks Disappear When Scrolling
Uicollectionview's Cell Registerclass in Swift
App Does Not Have Access to Your Photos or Videos iOS 9
How to Add a Button to the Mkpointannotation
iPhone Ad Hoc Build Using Xcode 4
How to Apply Multiple Transforms in Swift
Cocoapods Not Installed or Not in Valid State
Centering Subview's X in Autolayout Throws "Not Prepared for the Constraint"