Iphone 3d Animation - iphone

I recently posted my problem but neither did I get an answer here or elsewhere, nor can I find my post again...
Anyway, I want to try to state my point clearer, hoping you can help me this time maybe.
The part of code, this is about, looks like this:
CABasicAnimation *animation = nil;
CATransform3D transform;
animation = [CABasicAnimation animationWithKeyPath:#"transform"];
transform = CATransform3DMakeRotation(1.57f, 0.0f, 1.0f, 0.0f);
value = [NSValue valueWithCATransform3D:transform];
[animation setToValue:value];
[animation setAutoreverses:YES];
[animation setDuration:0.5f];
[[shieldView layer] addAnimation:animation forKey:#"180"];
What happens, is that I have a UIImageView with an image in it. I take this View and rotate it around the z-Axis for half a turn (1.57 measured in arc).
Now there is another View overlapping with the one being transformed in 3d. This leads to my problem: As soon as the transformation is executed, the transformed layer is sort of clipped against the overlapping view, but wrong, so that u see a 'flickering' effect to both Views.
Now I don't know, why this happens. I would expect the view to be animated appropriately, without this 'bug', and the Views to be just displayed correctly.... since I do not do anything special.
I have tried to overlay 2D transformations, using the 'beginAnimations' and 'commitAnimations' context, which works fine. This means, the problem is sort of hidden in the 3D rotation of my View.
You guys have any clues on this? I hope I explained that well enough.

If these are two sibling views (subviews of the same superview), their layers can overlap, potentially creating the visual artifacts you see. You should be able to either reposition the views relative to one another in the view hierarchy (make one view a level above or below the other) or directly set the Z position of the view's layer. If you do something like
shieldView.layer.zPosition = 1.0f;
your shieldView's layer should be slightly above the other view's layer (unless I'm remembering the coordinate space wrong and it needs to be -1.0f) and you should be able to avoid the clipping you see now.

Related

CATransiton Flicker w/ background animations

I am using a CATransition to shuffle CALayer's in and out of a UIView (the UIView isn't fullscreen.) The new layer enters from the right and the old layer leaves to the left. The CAlayer's have their contents properties set to CGImageRefs. Here is what I believe to be the pertinent code:
CATransition *transition = [CATransition animation];
transition.duration = transitionTime;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.delegate = self;
[view.layer addAnimation:transition forKey:nil];
// onDeck is the layer stage-right and is about to enter
[view.layer addSublayer:onDeck];
// onStage is the layer currently in the middle of the view and is exiting
if (onStage)
[onStage removeFromSuperlayer];
This animation occurs, there is a 1 second pause, and then a new image is animated in etc, etc. This works beautifully in the simulator but on my 2nd generation iPod Touch, there are occasional hiccups in the animation. Specifically, the layer being animated in will flicker on top of the currently displayed layer. These flickers are not consistent but are noticeable.
What I've narrowed down to be the likely culprit(s) are the background animations I have going on behind this transition. There are a few dozen CAlayer's flying in and out of the full-screen view in the background. When I remove these background animations or set the animation duration for the transition to a much higher duration (2 seconds +) the animation performs fine (I'd like the animation time to be 0.75 seconds.)
My first thought (which seems to be backed up by the above observations) is that I am pushing CoreAnimation (at least for my iPod) too hard and need to compromise. Why I am having trouble accepting this is that the scene renders very nicely (little to no lag) aside from this occasional flicker.
If anyone has any input on this issue, or CoreAnimation optimization in general, I'd be very much appreciative!
Thanks for reading
Update:
Had a chance to test this on an iPhone 4 and the flickering never occurred. Additionally, CoreAnimation instrument confirmed that, on my 2nd generation iPod Touch, I am consistently getting high 40s to low/mid 50s in FPS.
Just a guess: have you tried managing your CATransactions at all?
You might try bracketing your modifications to the scene like this:
[ CATransaction begin ]
... your animations ...
[ CATransaction commit ] ;
I would get rid of all shadows (if you have any) and then check if performance improves. I've seen that shadows, particularly shadows on CAShapeLayers, have a great impact on the smoothness of animations.

iPhone Dev: Animating PNG Sequences

What is the best or recommended technique for animating PNG Sequences.
Heres what I've learned:
Do it Manually
Using MutableArrays containing Strings, you can animate a UIImageView with a timer which increments an index number
UIImage - animation methods
This works, the only problem is to find if an image has completed its animation, you have to check the isAnimating BOOL, and to do that you need a timer.
What is the best and recommended?
Looking to do Oldschool game sprite animations,
ie:
Idle Animation
Attack Animation
Walk Animation
ect...
Let me know if any one has something.
#lessfame
Example to animate arrows
UIImage* img1 = [UIImage imageNamed:#"fleche1.png"];
UIImage* img2 = [UIImage imageNamed:#"fleche2.png"];
NSArray *images = [NSArray arrayWithObjects:img1,img2, nil];
UIImageView* imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 160.0, 160.0)];
[imageView setAnimationImages:images];
[imageView setAnimationRepeatCount:100];
[imageView setAnimationDuration:3.0];
imageView.center = myView.center;
[imageView startAnimating];
[myView addSubview:imageView];
[imageView release];
Easiest way is to use Core Animation layers to do sprite animation:
Make a 'multi-cell' image strip (could be PNG or JPG) of all the various moves for the sprite. Make each 'cell' be a fixed height or width.
Put the image in a UIImageView.
Take the CALayer of the view, and adjust the contentsRect property of the layer. This acts as a clipping rectangle for the sprite. To animate sprite all you have to do is move the contentsRect over to the next cell position in the image strip.
Something like this will do it (assuming you've already calculated the newSpritePosition.
[CATransaction begin];
[CATransaction setDisableActions:YES];
spriteLayer.contentsRect = newSpritePosition;
[CATransaction commit];
(If you don't do the second line, then you'll get a default slide animation instead of a 'jump' to the next state.)
With this technique you can rotate through all the frames of the sprite -- much like a flipbook. CALAyer transactions are optimized so you should get pretty fast frame rates. You can set an animationDidStop completion handler to move to the next state of the sprite or loop back to the beginning frame.
It depends on how you are going to use the sprites. If you just need a simple looping sprite then the UIImage method is great. If you want more granular control then you will be happier loading the images into an array and cycling them using a NSTimer to handle the timing. Personally I use the array method most often because it leaves me more options in the future (like detecting when animations have completed). One more suggestion would be to check out the cocos2d project. Its sprite is alot more powerful than either of these suggestions.
As I said in another answer, I found this to be a good way: PNG Animation method by Moses DeJong
From his words:
This example implements an animation oriented view controller that simply waits to read the PNG image data for a frame until it is needed. Instead of alllocating many megabytes, this class run in about a half a meg of memory with about a 5-10% CPU utilization on a 2nd gen iPhone.
I'm still unsure exactly how it's done. I believe it basically uses UIImageView to cache up AVAudioPlayer.

Core-Plot iPhone Animation Examples

I've been looking into core-plot for the iPhone and I'm having trouble finding any examples of animation actually being used.
What I need to see is an example of how to use core-plots animation to add an extra plot to a graph when someone clicks a button.
If anyone can produce and example, or show me a link to one, that would be great.
Regards,
Craig
The official CPAnimation classes within Core Plot are just stubs right now. At some point, we'll enable the full functionality of those.
In the meantime, every visible element in Core Plot is a Core Animation CALayer, so you can animate these using existing Core Animation methods. For example, if you have a plot called dataSourceLinePlot (like in the test Core Plot iPhone application), you could start the plot off with an opacity of 0.0:
dataSourceLinePlot.opacity = 0.0f;
[graph addPlot:dataSourceLinePlot];
and then animate its opacity to fade it in:
CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:#"opacity"];
fadeInAnimation.duration = 1.0f;
fadeInAnimation.removedOnCompletion = NO;
fadeInAnimation.fillMode = kCAFillModeForwards;
fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0];
[dataSourceLinePlot addAnimation:fadeInAnimation forKey:#"animateOpacity"];
This will fade in a new plot on an existing graph over a one second interval. You could also do something similar to animate it in from a side or use a transform to scale it up into position. CATransitions could also be used to achieve these kind of effects.
EDIT (1/17/2010): The Core Plot iPhone test application now contains an example of the fade-in animation described above.

How can I replicate the trashing animation of Mail.app

In my iPhone app, I have put a UIBarBUtton of type UIBarButtonSystemItemTrash in my UIToolBar. When pressed, I'd like to replicate the animation of Mail.app: the bin opens, the UIView folds and flies into it.
Is there a way to access this animation ithrough the iPhone SDK?
Presently I am using a custom made animation, but there are some limits; for example, I cannot animate the bin itself.
Do you have any suggestion? Code samples?
Cheers,
Davide
Use the suckEffect type on an animation. Also: spewEffect, genieEffect, unGenieEffect, twist, tubey, swirl, cameraIris, cameraIrisHollowClose, cameraIrisHollowOpen, rippleEffect, charminUltra, zoomyIn, and zoomyOut. Doesn't work in the simulator.
CATransition *animation = [CATransition animation];
animation.type = #"suckEffect";
animation.duration = 2.0f;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
view.opacity = 1.0f;
[view.layer addAnimation:animation forKey:#"transitionViewAnimation"];
Note: Code snippet was pulled from a larger codebase. I hope it works :)
Just to add some info:
You can use "suckEffect" with the standard +[UIView setAnimationTransition:forView:cache:]. Just pass the number 103 to the animationTransition variable. This won't avoid your app being rejected by Apple though :p
"spewEffect", "genieEffect", "unGenieEffect", etc. no longer exist on iPhoneOS 3.x. The only undocumented transition left are "cube" (--), "rippleEffect" (110), the three "cameraIris" effects (105,106,107) and "suckEffect" (103).
See http://www.iphonedevwiki.net/index.php?title=UIViewAnimationState for detail.
Also, to animate the bin (with private API): http://www.iphonedevwiki.net/index.php?title=UIToolbar#Animating_the_trash_can_icon.
Unfortunately, I think this is going to need to be an entirely custom animation. The UIView folding can be approximated using Core Animation, perhaps by adding perspective to the CATransform3D of the UIView's underlying layer to distort the UIView into a trapezoid which gets sucked into the trash can.
As far as the trash can, you can create a UIBarButtonItem using initWithCustomView:, which might let you insert a custom UIView that has an animatable trashcan. It looks like the trash can has two elements, the can base and the lid, which are rotated independently to open and close the can. Draw PNGs for both, make UIImageViews for them, and make them subviews of the UIBarButtonItem custom view. For opening and closing, apply rotational transforms to them to animate the subviews.
I'm not sure if this is an answer but here is lib that do "genie effect" so it's quite similar to what you want achieve.
CGRect endRect = CGRectMake(30, 40, 50, 60);
[view genieInTransitionWithDuration:0.7
destinationRect:endRect
destinationEdge:BCRectEdgeTop
completion:^{
NSLog(#"I'm done!");
}];

CATransition showing a single frame from the end of the transition before the animation starts

I am using some code which was originally taken from the Apple sample ViewTransitions to swap two views with each other.
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionFade];
[animation setDuration:0.3f];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[[container layer] addAnimation:animation forKey:#"swap"];
When my transition executes on the devlice, I sometimes get a single frame flash of the final frame of the transition animation and then the animation plays smoothly. This gives a very jarring effect of the 2nd view which flickers in and then out again before the smooth animation executes.
The main difference between my example and the Apple example is that my views are not full screen, I have a container UIView which contains both sub-views and I am applying my animation to the container layer instead the root view layer. I can not see that this should make much difference though.
This issue does not happen at all in the simulator and is intermittent (about 60-70% of the time) on the device. Is anyone else seeing this behaviour and if so, how did you work around it?
Updated with more information:
The code was originally part of a multi part animation but I moved it to be triggered by a button to isolate the problem. The issue occurs in both situations.
The animation delegates were implemented but have been removed to try and isolate the problem.
The views are not changing during the animation and in fact [container setUserInteractionEnabled:NO] is being called (but the problem also happens without user interaction being disabled).
I have tried starting the animation from the middle of the transition and ending before the end using setStartProgress and setEndProgress, again the problem persists.
I have tried slowing the animation duration right down as well with no effect.
To begin to answer your question more information is needed - for instance, how are you calling that code (e.g. is it bound to a button as an action or is it triggered automatically somehow), have you implemented the delegate methods to start and stop the animation (and what is contained within them), and are your views changing at some point during the animation? Timing between the simulator and device will be off - you should not rely on the simulator to test animation as everything will happen quicker.
Solved, I had missed a key piece of this that I thought was irrelevant ;) After setting up the animation in the code sample above, I was swapping the views out in the same method.
Moving it to the animationDidStart delegate fixed the issue.