IPhone - 2d Animation - Translations of multiple objects - iphone

I would love if someone could give me a short breakdown on what's the best way in terms of memory usage for animating UIImageViews (translation, without sprites).
More specifically, I need to animate multiple objects on screen at the same time (let's say up to 15-20);
Also, I have to be able to interrupt the animation due to collision between some of these objects.
The kind of animation I need is a simple translation. If it's possible, I would concat this translation with rotations and scalings (secondary).
I'd prefer not to use OpenGL because I think that this kind ow work doesn't require it.
Thanks guys.

CoreAnimation can do this handily. The code below will animate the translation of a view. It's also possible to stop the animation half-way and get its current state for feeding into your collision detection algorithm, but you'll have to read up a bit on Core Animation for that.
[UIView beginAnimations:nil context:nil];
view.center = CGPointMake (view.center.x + 50, view.center.y);
[UIView commitAnimations];

Related

Tracking UIView frame change animation

I have a UITextView that changes it's frame with the animateWithDuration:animations method:
[UIView animateWithDuration:1.5 animations:^{
[_textView setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - keyboardSize.height-25)];
}];
Is there any callback that helps me track the height of the UITextView as it animates?
There is no accurate way.
That's because the frame is just set directly. The animation takes care of the transition, but actually there is no transition.
There are some ways of estimating what is the current frame size and for me, the best is the simple math solution using a timer, when the animation started and the animation duration.
But, again, it's probably for the best if you just go another way, as this is certainly going to impact on your code cost and precision.
It's my first post and I don't really know anything that well, just learning and trying to help.
This depends on what you want to do with this thing.
If you want somehow accurate information about your frame, use the presentationLayer. This is a semi-accurate representation of what's actually on the screen. Note that this is in the coordinates of the view (bounds), so you need to convert it to the superview's coordinate system to get the current frame.
CGRect currentTextViewFrame = [_textView.superview convertRect:[_textView.layer.presentationLayer frame] fromView:_textView];
Note however this will be about one drawing loop or more off. If you are trying to base another animation off this it may be problematic and can cause flickering or other delay-induced effects. Also, at least the official documentation says this may not always be very fast and you may want to make the animation yourself if you need this information often due to performance reasons.
[_textView.layer.presentationLayer frame].size.height;
Credit belongs to this anwser.

Objective-c going down / up with acceleration

Im trying to make an animation of falling object that goes up when you touch the screen. That is not a problem if i want to use a linear velocity for this object, but i would better like it if it accelerated towards ground and when user touches screen it starts accelerating to the opposite direction. So lets suppose we have an object that goes 10px/s towards ground and when user touches screen i want it to have a = -5px/s^2 which means that even after touching screen, the object would still go down for another 2 seconds. Any idea how to do this in a "nice way" (right now im rewriting UIImageViews.frame every time with new CGRect but thats not really good way to do it i guess)?
Thanks
You can always use UIView animations:
[UIView animateWithDuration:1.0
delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
// put the co-ordinates you want your object to FINISH on in here
}
completion:^(BOOL finished){
}];
Any idea how to do this in a "nice way" (right now im rewriting
UIImageViews.frame every time with new CGRect but thats not really
good way to do it i guess)?
Use Core Animation. It's very easy to get started, and very powerful once you've gotten started. You can specify your own timing function, so you can give the appearance of acceleration. There's no reason for you to redraw your image view manually... Core Animation will do this for you more easily, and better.

Animate Train in iphone

I want to animate a 20 wagon train in iphone. The train will move left to right. Each wagon will have a different animation. I was confused how to do it. Because the images are large and 20 images at one time would cause memory warnings.
Can anyone suggest how to go about it. Should I use cocos2d for this?
Thanks!
I would do that in cocos2d.
I would create a 'Wagon'-class and then start by initiate two of them (just because I think that two wagons will fill the screen). And then start moving the wagons. Each time a wagon is completely out of the screen I would release it. When it's time for the next wagon I would initiate that and so on.
How many frames does the animations have, and how big are they? Maybe you'll have to make one atlas per wagon. You can always call:
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
and:
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
Cocos2D is best!
Create sprites, set actions to it and IMHO!!!
If you want to do using UIImageViews, look for
UIImageView.animationImages
UIImageView.animationDuration
UIImageView.animationRepeatCount
and
[UIView beginAnimations:(NSString *)animationID context:(void *)context];
[UIView setAnimationDuration:(NSTimeInterval)duration]
// make the changes in your view which you want to occur in given duration
[UIView commitAnimations];
But again, this will definitely give you a hard time, better go for Cocos2D.

How to create a controllable flip effect (flip as far (and fast) as you drag) of an UIView

I have a card (a flashcard you could say)
What I can do:
On fingersweeping over the flashcard the card gets turned. It's happening by detecting
touchesBegan and touchesMoved and then I do stuff like
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
if (left) {
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.flashCardView cache:YES];
}else{
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView:self.flashCardView cache:YES];
}
What I can't do (but want to):
I want to somehow drag the flip.
Imagine this, you have a flashcard and you think you know the answer, you start flipping the card around because you want to see if you are correct, but then... no stop... you hesitate, turn back the card to the way it was, rethink, get the real answer and then finally flip to see that you were right to hesitate.
Now I only have: once you start flipping, you can't stop it.
So do you have any hints on how to do this ? something to read ? I'm still at the beginning of understanding cocoa and iPhone development
EDIT I'm more experienced now, but I still haven't done such custom animations, maybe someone can give me a lift ?
You cannot achieve what you're trying to do with the preset UIView animations because the animation is one-time and cannot be intercepted. You can use OpenGL for true 3D transformations (what you need is rotation about an axis), or for a speedier implementation try CALayer transforms as drawnonward suggested.
Here is an example of the interactive 3D page flip implemented in OpenGL. It uses private APIs, but it might help you understand how to respond to user input and apply transforms appropriately.

Source of UIView Implicit Animation delay?

I have a block of UIView animation code that looks like this:
[UIView beginAnimations:#"pushView" context:nil];
[UIView setAnimationDelay:0];
[UIView setAnimationDuration:.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:#selector(animationWillStart)];
view.frame = CGRectMake(0, 0, 320, 416);
[UIView commitAnimations];
The code basically mimics the animation of a ModalView presentation and is tied to a button on my interface. When the button is pressed, I get a long (.5 sec) delay (on iPod Touch...twice as fast on iPhone 3GS) before the animationWillStart: actually gets called. My app has lots going on besides this, but I've timed various points of my code and the delay definitely occurs at this block. In other words, a timestamp immediately before this code block and a timestamp when animationWillStart: gets called shows a .5 sec difference.
I'm not too experienced with Core Animation and I'm just trying to figure out what the cause of the delay is...Memory use is stable when the animation starts and CoreAnimation FPS seems to be fine in Instruments. The view that gets animated does have upwards of 20 total subviews, but if that were the issue wouldn't it cause choppiness after the animation starts, rather than before? Any ideas?
Try it with a single subview or with no subviews at all to make sure the delay is not caused by so many children.
Profile the code in Instruments to see where exactly the code lags. You might get down to some internal Core Animation function call that will hint you what’s going on.
Try the code without the “lot that’s going on” to make sure you’re not stepping on Core Animation’s toes with your other code.
Or, in short: experiment and measure, because conjectures seldom work when optimizing.
In your pasted block, you specify the selector animationWillStart (no colon), but later in your question, you refer to animationWillStart: (with colon). These selectors are not equivalent, so is it possible that your intended selector is never being called on account of this animation, and is being called 0.5 seconds later on account of some other animation?