I am doing the core animation. Here my CALayer wants to pause and resume more than 5 times during animation. Currently i am using [Self performSelector: afterDelay: ] and Timers to implement delays. For implementing now i am using 5 timers , i think it's bad style of coding i am using. So is there any other better way to implement the delay.
Now i am doing the pictureBook while reading the text i have to move an image along with it. It's successfully implemented. But to adjust the movement of image according to the voice over, i have to pause the layer and resume it according to voice played. For every page i have six languages too, so the delay are different for every languages , Likewise i am having 20 pages.
Use explicit animations and the CAKeyframeAnimation class with its timing functions to define the animation and its timing more precisely.
See also the Core Animation Cookbook (especially the dedicated "Timing" section) and the Core Animation Programming Guide in Apple's documentation.
Related
I'm working on an iPhone App where I rely heavily on timers and animations, but I've realized my game is really slowing down and lagging on certain aspects of the game. I'm not quite sure how to improve this without removing any animations or anything.
Essentially what I'm using is the accelerometer to update my character's position (Left/Right). I also use several timers to read from different URLs, update images and the one that lags the most is one that loops an image to move from left to right.
Basically I'm using about 6 or 7 timers and the Accelerometer, is there a way I can improve the performance of my game without having to remove any of my animations or changing the interval of the timers?
Thanks in advance!
Try use Allocation
RUN-> RUN WITH PERFORMANCE TOOLS->Allocation
to see which part is overload in the application
Instead of using NSTimer to animate, you might want to look at using the animationImages property in UIImageView (which lets you show multiple frames of animation, possibly looping) or beginAnimations within UIView (which lets you move an object along a path, among other things).
A good place to start is with this question on recommend reading for iPhone animation, although for reference the documentation in XCode and Apple's programming guides are good sources by themselves.
What others have suggested - in terms of using a game loop - make sense, too, but depending on the complexity of your game, sometimes just letting the iOS SDK take care of your animations for you can be good enough.
I have been playing around with the two different ways of doing UIView animations: begin/commit and Blocks.
I have noticed that the beginAnimations:context: / commitAnimations way of doing things is nicely asynchronous, keeping the UI free while the animation is running.
However, I also noticed that the animateWithDuration:animations:completion way seems to block the UI, making it unresponsive while the animation is running.
I thought one of the main points of using blocks was to achieve asynchronous execution easily. Why does the blocks variant of the UIView animarions block the UI while the begin/commit variant does not?
Edit:
My question originally assumed that the blocks animation was a synchronous operation and blocked the UI. As it transpired from Jeff Kelly's answer, that this isn't the case. My original assumption was incorrect, the blocks animation is not synchronous. See Jeff's answer for the details.
Are you using the right UIView class method? If you use +animateWithDuration:delay:options:animations:completion:, you can specify a bitmask of options. One of the possible options is UIViewAnimationOptionAllowUserInteraction, which sounds like just what you want.
Im trying to find the best way to avoid having tiny UI lockups after certain events in my app. For example here are two cases where i have come across mini-lockups:
I have a button that when pressed loads a local mp3 file (around 20-30mb) using AVAudioPlayer, calls the prepareToPlay method and then plays the audio file. The issue is that the button has the showsTouchWhenHighlighted flag set to yes and after pressing it it stays highlighted until the audio file begins playing which could take 1-3 secs.
Another similar example is using a navbar button to sort and reload the table data. There is a very short but noticeable lockup where the button remains highlighted until the table has reloaded.
Can anyone suggest a good approach to minimizing/eliminating these mini lockups? I didnt really come across any code to achieve this in any of the books/tutorials i read that dealt with tableviews and avaudioplayer. Should i be launching these actions on different threads?
thx
For number 1, your best bet is to load the item on a background thread and inform the user that you're doing so (either via a loading HUD or some other indicator). The simplest way of doing this will be to use - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;. If you're running iOS 4.0 + you may want to look into executing block callbacks and see if they will work for you.
For number 2, perform the sorting on the background thread or change your sorting method (consider using a sorted data structure rather than resorting after inserts?). reloadData should occur only on the main thread.
I'm an iPhone noob myself, but it sounds like your code is stuck doing synchronous actions, which will guarantee that your UI gets locked up until the action is done executing.
Although I don't have an explicit answer, look for asynchronous options to perform these actions as they will not lockup your UI. These are usually achieved through using threads or deferred objects. From my experience so far w/ Objective-C, most actions your program neds to take can be achieved through async actions.
I have an scroll view with some sophisticated animations happening during scrolling. Although after 2 weeks of finetuning the performance is acceptable now, the scrolling is not 100% smooth when the animations happen.
I know that core animation does animations in a background thread. But I wonder if it would help to split those animation blocks (10 of them at pretty much the same time) into threads.
There are a few methods that look interesting:
– performSelector:onThread:withObject:waitUntilDone:
– performSelectorInBackground:withObject:
or is that nonsense to do?
No, it won't help. As you correctly stated yourself, Core Animation already runs in a seperate thread. Core Animation is smart enough to handle animation blocks as efficiently as possible. I wouldn't advise interfering with it.
The Core Animation Programming Guide says:
An abstract animation interface that
allows animations to run on a separate
thread, independent of your
application's run loop. Once an
animation is configured and starts,
Core Animation assumes full
responsibility for running it at frame
rate.
Are you sure the choppy behavior is really from CA? Do you have anything else going on?
If you have any background network access, consider moving that into a separate thread - the time taken to service those calls takes away from time the UI spends updating the screen as you scroll.
We have an app in AppStore Bust~A~Spook we had an issue with. When you tap the screen we use CALayer to find the position of all the views during their animation and if you hit one we start a die sequence. However, there is a noticeable delay, it appears as if the touches are buffered and we we receive the event to late. Is there a way to poll or any better way to respond to touches to avoid this lag time?
This is in a UIView not a UIScrollView
Are you using a UIScrollView to host all this? There's a property of that called delaysContentTouches. This defaults to YES, which means the view tries to ascertain whether a touch is a scroll gesture or not, before passing it on. You might try setting this to NO and seeing if that helps.
This is a pretty old post about a seasonal app, so the OP probably isn't still working on this problem, but in case others come across this same problem and find this useful.
I agree with Kriem that CPU overload is a common cause of significant delay in touch processing, though there is a lot of optimization one can do before having to pull out OpenGL. CALayer is quite well optimized for the kinds of problems you're describing here.
We should first check the basics:
CALayers added to the main view's layer
touchesBegan:withEvent: implemented in the main view
When the phase is UITouchPhaseBegan, you call hitTest: on the main view's layer to find the appropriate sub-layer
Die sequence starts on the relevant model object, updating the layer.
Then, we can check performance using Instruments. Make sure your CPU isn't overloaded. Does everything run fine in simulator but have trouble on the device?
The problem you're trying to solve is very common, so you should not expect a complex or tricky solution to be required. It is most likely that the design or implementation has a basic flaw and just needs troubleshooting.
Delayed touches usually indicates a CPU overload. Using a NSTimer for frame-to-frame based action is prone to interfering with the touch handling.
If that's the case for your app, then my advice is very simple: OpenGL.
If you're doing any sort of core-animation animation of the CALayers at the same time as you're hit-testing, you must get the presentationLayer before calling hitTest:, as the positions of the model layers do not reflect what might be on screen, but the positions to which the layers are animating.
Hope that helps.