Synchronizing CAAnimations - iphone

I have a repeating animation that I need to synchronize with some other transient animations. The repeating animation is a scan line that moves across the screen for 4s. As it passes over images underneath, those images need to "blip."
The blipping images can come and go and move at the whim of the user. They are also not part of the same layer.
I can't figure out how to keep the scan line and the image animations in sync. I would consider adding them all to a CAAnimationGroup, but the "animations" property is a readonly NSArray, so it seems like I'd have to re-create the group every time one of the blipping animations is added, removed, or moves, which will be fairly often. I'm also guessing that creating a new group would mean the scan line animation would need to be restarted, causing it to be jerky.
According to this post:
=">CAAnimation that calls a method in periodic animation-progress intervals?
Core Animation is "time-based," but I'm not sure I fully understand what that means for a repeating animation and how reliable it is (I can't find this mentioned in any of the online documentation). Does that mean if I start the scan line repeating animation at time x, it will repeat at exact 4s intervals after it's been started? What about the app going to the background and returning or similar?
Thanks for your help!
Ryan

After fiddling with this for a bit, I found that I could synchronize my animations by making sure their beginTimes lined up. I started by setting the beginTime of the scan line animation:
scanAnimation.beginTime = CACurrentMediaTime();
From there I simply computed the offset within the 4s window (call it dt) and set the other animations' beginTimes to that:
blipAnimation.beginTime = scanAnimation.beginTime + dt;
This worked perfectly even if the beginTime was in the past; the animation engine actually extrapolated forward and animated the next blip dt seconds after the scan animation looped back.
The downside is that I've now absolutely bludgeoned the frame rate. I'm trying to find useful information about Core Animation performance, but so far to no avail. I've taken a pretty simple approach to laying out all of my images and animations so far and I'm prepared to rewrite a lot of code to optimize it, but I don't want to embark on a rewrite without some preparation. Any pointers to in-depth discussions about how Core Animation works would be really handy.

Related

How can I swap out a unity animation for another while keeping the same duration into the animation?

I've seen this question asked here but it was never answered, and mines a bit different.
As an example: lets say I'm making a character that's constantly on a looping animation, and I have a button that you can hold down to make the character wear sunglasses, the sunglasses are kept on a separate animation of the same framerate and frame count. How can I use the button to switch them but start the new animation on the same frame as the last?
Edit: I've found a function for animators called PlayInFixedTime() this is the documentation for it, I don't know what it does but it mentions a "time offset" so it could be what I'm looking for, but I have no clue.
In my opinion you can solve this in 2 ways:
Animation Events: via script you are able to select the end of an animation even if it is looping
Wrap mode: there is an example here (https://answers.unity.com/questions/37080/stopping-an-animation-from-looping-at-the-end.html) but basically you are able to play an animation in Queue after the end of the previous. You can do it with a simple function so you are able to reuse it many times

When using CAKeyframeAnimation, is it possible not to load all keyframes upfront?

I am working on an iOS application where I have some animations that I want to play. For each animation I have all the information in a file(initial position/scale/etc.. and then one keyframe per record in the file).
I am currently using CAKeyframeAnimation as that seemed the most logical choice, however, with some animations where I have a large number of keyframes it's taking ~2s to load all the animations upfront. I would really like to avoid that lag. Furthermore, the animation only really needs 2 keyframes at any point in time and loading all of them at once causes my app to have a very large memory footprint that I'd also like to avoid.
Is it possible to add keyframes on the fly to an already running CAKeyframeAnimation? If so, how?
If it's not possible, what should I use instead of CAKeyframeAnimation?

Is there any way to make an animation just using CGContext on iOS?

Well, I want to make a animation application on iOS. So, I make an application using UIViews... But, it's very complicated. There are so many UIViews so I want to make it simple. So, There's any way to make an animation just using CGContext just one UIView? If someone knows PLS help.
You could use a timer that repeatedly fires so you call setNeedsDisplay every 0.01 second or something, and calculate every rectangle, circle, line, whatever to the right places at every time instant. You may well suffer some issues this way, though, since drawRect won't get called instantly every time, meaning you'll need to check the actual time when drawRect fires. You might even need to take the time it takes to execute your code into account.
Or just move the UIViews around in stead, using animateWithDuration:. I recommend that. No matter how complex your hierarchy is, doing it all in a single view will always be more complex.

How can we get kCAOnOrderOut to work?

The Apple documentation claims that the Core Animation action key kCAOnOrderOut has one sole purpose: to animate a layer out of sight when it either becomes hidden or has -removeFromSuperlayer called on it. I'm only referring to the latter case in this question.
In practice, when -removeFromSuperlayer is called, the layer is removed immediately, and no animation is performed on it.
It's been hinted at that this is a difference between the Presentation and Model layers, but I'm not experienced enough in Core Animation to know what to make of this.
If anyone can explain how to force the animation to run before the layer is removed, when the animation is returned for the key kCAOnOrderOut, it would be appreciated by at least me and a few other people.
Thanks.
I have no idea how to implement it with the key kCAOnOrderOut, but I ran into a similar problem a while back. My fix was to set the animation with a specific duration and immediately send off a delayed timer that waited the same amount of time as the animation duration. After my timer fired I would remove the layer/view.

can't draw fast enough to keep up with touchesMoved?

I am trying to implement simple paint functionality in my iPhone app. I tried updating a bitmap with a bitmap brush, and I also tried this tutorial.
Both methods have the same problem, even though the code is almost totally different. It happens only on the device - the simulator works fine.
When I touch the screen and move my finger, the screen does not get updated. When I pause or lift my finger, then the screen gets updated. This is not a very good user experience!
I tried calling drawRect from touchesMoved directly, but found that the drawing context (which I retrieve using UIGraphicsGetCurrentContext) is invalid for many of the calls, so painting the screen myself for every touchesMoved doesn't work.
Any ideas?
Thanks for any help, this has been quite frustrating!
Henning
It sounds to me like you're not giving the main run loop a chance to update the display. Your drawing code may be taking longer to execute than the time between touch events, so the display is never updated. When you lift your finger, it does the updating because it's no longer burdened with your drawing.
You might consider optimizing your drawing to speed it up (drawing only within the dirty region of the screen, for example), using something like NSOperationQueue to queue up the heavy calculations of your drawing to run on a background thread, or selectively dropping touch drawing events to keep your response smooth.
One additional possibility is placing your heavy drawing code in a separate method and calling it via performSelector:withObject:afterDelay, with a 10 millisecond (or smaller) delay. This might give the main run loop a chance to update the display with its current state. I haven't tested this, but if I remember correctly I've seen this work.
You can't directly call drawRect:. To refresh your screen on demand, try calling [self setNeedsDisplay] from your touchesMoved method, which will setup the proper contexts for a call to drawRect:.