I've looked at the methods for block based animation and noticed there is no equivalent parameter or option for [UIView setAnimationRepeatCount:].
What's the simplest way to repeat an animation a fixed number of times? Do you, for instance, chain them using the completion block?
I just asked a similar question and then I read the 2010-11-15 release of the View Programming Guide for iOS. Page 64 caught my attention.
In the animation block, one can still use the [UIView setAnimationRepeatCount:]. I thought that I could/should not. So my ability to read Apple doc needs to improve.
So perhaps this would solve your (and my need). I'm trying it later today
As #PommeOuest mentioned. You can still user [UIView setAnimationRepeatCount:] inside the animation block. I just tried in my project and it works well.
I'm using XCode4 and iOS5.
Set a completion callback - re-initiate the animation in it - and keep track of the counter yourself.
Related
I'm using CCAnimate to animate my CCAnimations. What I want is reuse CCAnimate action, so, when I want to play another animation I do something like:
[_animateAction setAnimation:animation];
This works more ore less, the problem is that the internal elapsed time for the animation is not reset, setAnimation is just setting the new animation. Is there any way reset an action in cocos2D? I have been lurking through the code and documentation, and it doesn't seem to exist any method to accomplish this.
Does anyone know what is the "best practice" in this situation?.
There's been a lot of confusion about reusing actions in Cocos2D. Apparently the docs say you should "initialize" the action again but this may not be working for all actions and it's definitely considered a bad practice to send the "init…" message to an already existing object again. This is similar to how you're not supposed to send dealloc manually to an object, yet you can do it.
Nevertheless, that's the way it is supposed to be for Cocos2D actions, so in your case to re-use the same animation action you would have to send it the appropriate init… message again:
[animation initWithDuration:5 animation:anim restoreOriginalFrame:YES];
[_animateAction setAnimation:animation];
As a side note, there's been a suggestion for mutable actions in the Cocos2D issue tracking system for two years now. The submitted code patch isn't going to work without modifications with the current Cocos2D version but it may be used to create your own mutable actions should the need arise.
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.
I'm currently animating many images via 4 UIImageViews, and all is well on that front. The animations complete as expected, and I am assuming that they run inside their own NSThread, as execution continues despite the animation. Of course, this is good and expected behaviour, as I definitely wouldn't want my whole app to halt until the animation finishes.
However, I need to kick off a method which needs to depend on whether the animation is running or not.
The following code is bad as I understand, as introducing loops and other delays inside the main thread causes instability.
while([self.fooImgView isAnimating])
;
This code effectively halts execution of the whole app. I need to find a way to "spin" until the animation completes, without wedging the app.
Any advice on this would be greatly appreciated.
Thanks!
sc.
If you use block animations like this one, you can use the completion block to call some delegate or execute your method
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.
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.