Hidden CATransition animations on iOS 4 (camera iris animation) - iphone

I'm trying to achieve the camera iris animation from the Apple camera app. It is also found in numerous other apps like RedLaser, Sudoku Grab, so it seems to be fine with Apples rules even thou it's private.
The hidden CATransition animations are dokumented here for example:
http://iphonedevwiki.net/index.php/UIViewAnimationState
However I'm not able to get any of the hidden ones to work, public ones work fine thou. Could this be a change of iOS 4? All information I do find on those hidden animations seems a little dated.
Here is my code:
CATransition *animation = [CATransition animation];
animation.delegate = self;
animation.duration = 2.0;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.type = #"cameraIris";
[self.window.layer addAnimation:animation forKey:nil];
Using "reveal" as 'animation.type' works fine with my code.
Has anybody played around with those on iOS 4 yet? Or is the issue totally different?
RedLaser uses this effect on iOS 4 (it's not an iOS 4 optimised app thou).

The animation is found in these other apps because it is Apple's implementation. Accessing the camera API will cause the shutter opening animation to appear. If you want to use this animation for your app in a non-camera api related way, then you will have to roll your own animation.

Related

Paper 'Unfold' Animation on a UIView

I want to create an 'unfold' animation to a UIView that appears on the screen.
An example of the animation can be viewed in this YouTube video that reviews the SuperList app (Another example of the animation can be viewed in the app's App Store page in the screenshots section).
I have quite good understanding of Core Animation and Objective C, so as with Cocoa and Cocoa Touch. The app will support versions 5.x and 4.x of iOS so, if it is possible, I would prefer a solution that suits both cases.
Moreover, I have googled this question about a thousand times and failed to get any answers, so help will be much appreciated. Thanks ahead, iLyrical.
Apparently, the 'UnCurl' effect is built-in with the framework and is your to use!
All you have to do, is use the animateWithDuration: animation: method of the UIView class and include the animation as follows:
[UIView animateWithDuration:1.0
animations:^{
CATransition *transition = [CATransition animation];
[transition setDelegate:self];
[transition setDuration:0.7];
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[transition setType:#"pageUnCurl"];
[self.view.layer addAnimation:transition forKey:#"pageUnCurl"];
[self.view addSubview:someView.view];
}];
The note image (white page) in this case has transparent section (all side) and thus when uncurl happens it looks like only the white part is uncurling.

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.

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.

How can I switch Content Views with an water-effect transition?

In the Photos app, there is a nice water drop effect used for transition. I had seen an app a while ago that used this same water effect transition for it's content views.
Unfortunately, this transition type is not listed in the UIViewAnimationTransition documentation. But since this third party app used it (I don't remember it's name), I guess that there is a way of using it.
Does anyone know?
I think it's just a hidden CATransition type:
CATransition *transition = [CATransition animation];
transition.type = #"rippleEffect";
transition.duration = 5.0f;
transition.timingFunction = UIViewAnimationCurveEaseInOut;
[self.layer addAnimation:transition forKey:#"transitionViewAnimation"];
(Note: I haven't tried this for rippleEffect but I have used suckEffect and spewEffect similarly)
It is not part of the published SDK. If you want to sell your app in the app store, you need to implement this yourself.