1

This is probably an easy answer, but I cannot find any information on it anywhere. I have an animation that transforms the x value of a label. If a certain task completes, the animation stops early and the completion action occurs. With this in mind, is there a way I can use the animation duration to determine if the timer ran out first or if the task completed?

I have a boolean that I was using to do this called taskComplete, but when I reset the view for the next level the completion sees the boolean as false and runs the code. For example, is there a way in xcode to do something like:

completion:^(BOOL finished) {
    //boolean is false and animation has lasted the amount asked or greater
    if (!taskComplete && animationDuration > animationTimer) {
        //do this
    }
}

All help is appreciated thank you!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Kiley
  • 409
  • 1
  • 5
  • 19
  • 1
    What about the `finished` param for the completion block? – i_am_jorf Aug 03 '15 at 14:25
  • What are you using for animation? Standard UIView methods or you animate yourself using Core Animation? – Jiri Trecak Aug 03 '15 at 14:25
  • I am using UIView methods @JiriTrecak – Kiley Aug 03 '15 at 14:27
  • @i_am_jorf can you explain that? – Kiley Aug 03 '15 at 14:38
  • Why exactly do you need to know what have finished first? I feel that you are trying to solve a problem which you shouldn't even encounter. – Sulthan Aug 03 '15 at 14:56
  • @Sulthan it is a level in a game and the transformed label is the timer. Whenever I reset the game, meaning the person completed the task, I reset the boolean that the task was completed, and the animation for the timer starts and resets. During this time, it completes the animation, and for some reason even if the task was completed always returns the results (the results as if the timer ran out first). I thought figuring out how long the animation lasts could be a good indicator of if the person finished the task or not. Any other ideas are appreciated! – Kiley Aug 03 '15 at 15:02
  • @Kiley No. Xcode is an IDE. Your question isn't about the IDE. Please read the tag's description. – rmaddy Aug 03 '15 at 15:17
  • 1
    @Kiley Nope, you should never base calculations on the duration of an animation. That's definitely wrong. We could probably help you to find a better solution if you can provide more relevant code. – Sulthan Aug 03 '15 at 15:34
  • @Sulthan I think the problem I am having is that the animation is continuing after the task completes, hence the completion -- the condition ends up being true for I reset the boolean before the animation completes. To do this, I tried `[self.view.layer removeAllAnimations];` but it does not seem to be removed. I think I am going to close this question becasue it does not seem to be possible and open another on the subject. I will link the new question here. – Kiley Aug 03 '15 at 15:48
  • @Sulthan would you like to change your comment to an answer and I will mark it as correct? – Kiley Aug 03 '15 at 15:59
  • 1
    Give a shot to POP framework from facebook - it allows you to stop animation as you wish; also, you should accept the answer if it was helpful, even though you did not get everything you needed – Jiri Trecak Aug 03 '15 at 17:09

2 Answers2

1

There is way how to retrieve current animation status, though I have to say you are not supposed to do it (but if you need, what can you do :)

CALayer has method called .presentationLayer (docs):

The layer object returned by this method provides a close approximation of the layer that is currently being displayed onscreen. While an animation is in progress, you can retrieve this object and use it to get the current values for those animations.

So on that layer, you can choose whatever attribute and run your condition against it. You can also add KVO to track any changes (and access it through view.layer.presentationLayer.attribute)

Other than that, you would have to use Core Animation or POPFramework from Facebook to track changes in greater detail.

Hope it helps!

Edit: I forgot to mention, if you need to know time, you can always calculate it from current value and start / end value as ((currentValue - startValue) / (endValue - startValue)) * animationTime, so there is no need to track it differently.

Jiri Trecak
  • 5,092
  • 26
  • 37
  • `.presentationLayer` sounds like exactly what I need, but how would I implement it into my project? Is there a special way to indicate this? Also, on your comment about startValue endValue, the problem is I do not know how to find what the end value is if the animation ended early. – Kiley Aug 03 '15 at 14:52
  • You can calculate time that way only if the animation interpolates the values linearly (`UIViewAnimationOptionCurveLinear`), which is usually not the case. – Sulthan Aug 03 '15 at 14:53
  • but you have endpoint of your animation (so if you have like animate opacity 0 -> 1 and the opacity is 0.3, it would be ((0.3 - 0) / (1 - 0)) * 10s = 0.3 / 1.0 * 10 = 3 sec :) so you know that animation went for 3 seconds – Jiri Trecak Aug 03 '15 at 14:54
  • you can use presentation layer to get those values like this: `let currentOpacity = layer.presentationLayer.valueForKeyPath("opacity")` – Jiri Trecak Aug 03 '15 at 14:56
  • @JiriTrecak That equation is valid only for linear interpolation, it won't be valid for `UIViewAnimationOptionCurveEaseInOut`, for example. – Sulthan Aug 03 '15 at 14:57
  • @JiriTrecak I am not animating for the alpha, I am using transform to change the horizontal size of the label, for lack of a better way of explaining. Using `.transform` means that the x value does not actually change, so I cannot calculate what the new x value is and how long the duration was to reach the new x value – Kiley Aug 03 '15 at 14:58
  • @Kiley you can use valueForKeyPath("transform.scale") to check for transformation changes – Jiri Trecak Aug 03 '15 at 15:00
  • @Sulthan true, I was just providing example -> there are definitely ways how to calculate it using standard Core Animation functions though – Jiri Trecak Aug 03 '15 at 15:01
  • @JiriTrecak it seems like valueForKeyPath works for arrays for the most part. What would the object be that it would be under? UIView? the animation itself?? I cannot seem to find it. – Kiley Aug 03 '15 at 15:13
  • 1
    @Kiley view that you are transforming ; you can read more here http://stackoverflow.com/questions/20244933/get-current-caanimation-transform-value – Jiri Trecak Aug 03 '15 at 15:14
  • @JiriTrecak I tried the method they explained on the other question you sent, but just like the person who asked the question their method still returned the same value whether or not the timer ran out first or the task was completed. – Kiley Aug 03 '15 at 15:21
0

As @Sulthan stated, you should never base calculations off the duration of an animation. With this in mind, I opened another question on the same subject matter here: https://stackoverflow.com/questions/31791748/objective-c-animation-not-stopping

Community
  • 1
  • 1
Kiley
  • 409
  • 1
  • 5
  • 19