Transition behavior using transitionFromView and transitionWithView - iphone

I am attempting to create a transition between two subviews (view1 and view2). When a button is pressed I want view1 (front) to flip and show view2 (back). I have tried both transitionFromView and transitionWithView. Each works - but each has a problem.
transitionFromView - flips the superview (the whole window view flips, not the subviews). When this flip happens - one subview is on the front of the superview before the flip, and the other subview is on the back of the flip - as it should be. But I don't want the superview to flip, just the subviews.
transitionWithView - flips only the subviews - but the 'to' view gets displayed before the transition happens.
Anyone have a suggestion?
-(IBAction) button1action:(id) sender {
if ([sender tag] == 0) {
[UIView transitionFromView:view2 toView:view1 duration:2.0
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:nil];
}
else {
[view1 removeFromSuperview];
[self.view addSubview:view2];
[UIView transitionWithView:view2
duration:2.0
options:UIViewAnimationOptionTransitionFlipFromRight +
UIViewAnimationOptionShowHideTransitionViews
animations:^{}
completion:nil];
}
}

You need to remove and add the subviews in the animation block. Also, I think that transitionWithView is supposed to take the super view as argument. I think what you need to do to get this right is to use a container view that is the same size as the views you want to flip.
This is copied from the documentation:
[UIView transitionWithView:containerView
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ [fromView removeFromSuperview]; [containerView addSubview:toView]; }
completion:NULL];

I have run into this exact same problem, and I agree with the earlier answer. It seems you must have a container view for animating a transition from one subview to another subview.
I'm using the transitionFromView approach. To have a background behind the animation, you will also need a superview with the background for the container view.
My code looks like:
[UIView transitionFromView:view1
toView:view2
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight |
UIViewAnimationOptionAllowUserInteraction |
UIViewAnimationOptionBeginFromCurrentState
completion:nil];

Here's my working solution stub, a simple thing that took 2 hours, damn:
we got 1 button to flip things, a UIView called panel that holds the 2 views I want to swap with a flip animation.
-(void)viewDidLoad{
[super viewDidLoad];
UIButton *btnFlip = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnFlip.frame = CGRectMake(10, 10, 50, 30);
[btnFlip setTitle:#"flip" forState:UIControlStateNormal];
[btnFlip addTarget:self action:#selector(flip) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btnFlip];
panel = [[UIView alloc] initWithFrame:CGRectMake(10, 40, 300,300)];
panel.backgroundColor = [UIColor darkGrayColor];
[self.view addSubview:panel];
panelBack = [[UIView alloc] initWithFrame:CGRectMake(10, 40, 280, 200)];
panelBack.tag = 1;
panelBack.backgroundColor = [UIColor brownColor];
[panel addSubview:panelBack];
panelFront = [[UIView alloc] initWithFrame:CGRectMake(10, 40, 280, 200)];
panelFront.tag = 2;
panelFront.backgroundColor = [UIColor whiteColor];
[panel addSubview:panelFront];
displayingFront = TRUE;
}
-(void)flip{
[UIView transitionWithView:panel
duration:0.5
options:(displayingFront ? UIViewAnimationOptionTransitionFlipFromRight : UIViewAnimationOptionTransitionFlipFromLeft)
animations:^{
if (displayingFront) {
//panelFront.hidden=TRUE;
//panelBack.hidden = FALSE;
[panelFront removeFromSuperview];
[panel addSubview:panelBack];
}else{
//panelFront.hidden=FALSE;
//panelBack.hidden = TRUE;
[panelBack removeFromSuperview];
[panel addSubview:panelFront];
}
}
completion:^(BOOL finished){
displayingFront = !displayingFront;
}];
}

Having run into the same problem I agree with Eric and Sam:
either transitionWithView or transitionFromView will both do what you want as given above as long as you create a container view of the appropriate size that you wish to flip. Otherwise the whole window view will flip.
So if view1 is the subview you begin with and you want to flip to view2 then add
UIView *containerView = [[UIView alloc] initWithFrame:appropriateSize];
[containerView addSubview:view1];
And then the simplest way to animate is probably:
[UIView transitionFromView:view1
toView:view2
duration:2.0
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:nil];

I had the same requirement, and saw many approaches -- from using layers (which ends up very complicated if you just want to deal with a UIView) to suggestions that i needed a "container" to then transition between to sub-views. But if you just want to swithc something front to back, like flipping over a playing card or a game tile, i made a one line change:
(note: i have an array of UIViews (tiles[x][y]) in a grid (for a game). i have all my imagefilenames in database tables / arrays, which dynamically are loaded into the UIImages of the UIImageViews. The image for the "back" of a card or tile in a UIImage named "tileBackPicImageNM".
so my code that simply swapped the front image out for an image of the back was:
[tiles[indexX][indexY] setImage:[UIImage imageNamed:tileBackPicImageNM]];
which works fine.
but and now, to show a flipping action, it is:
[UIView transitionWithView:tiles[indexX][indexY] duration:0.3 options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[[indexX][indexY] setImage:[UIImage imageNamed:tileBackPicImageNM]];
}
completion:NULL];
I experimented with different "duration" parameters -- subsequently made it a float that I set in the viewDidLoad routine. Faster than 0.3 is almost not visible, and a value of 1 or 2 is very slow...
This does not involve two sub-views, which is my case is a lot more useful since i didn't want to have an array of containers containing a hierarchy of views, etc... and on new levels etc i always reload the arrays anyway...

Keep in mind that the container view requires a solid background color.It means anything else than clear color.This was my mistake and spent quite long time to figure it out.

using transitionFromView, both front and back view should be inside another view(not the super view). this way it will not flip the whole screen.
> superview
> another view
> backview
> frontview
UIView.transitionFromView(frontView, toView: backView, duration: 0.5, options: .TransitionFlipFromLeft | .ShowHideTransitionViews) { finished in
}
You might want to make the (another view) equal to the size of the frontView

Related

Why won't UIButtons detect a touch in a UIView on a UIActionSheet?

I've added a UIView (which contains the UIImageView for the background, three UIButtons which say "Test" and the final UIButton to dismiss the view called "Finished") as a subview of my UIActionSheet.
Why won't any of these buttons detect touches? My UIView has User Interaction Enabled checked.
I'd appreciate some help with this as I've been pulling my hair out (not literally of course)!
Here's my set up:
If you're just looking mimic the UIActionSheet, I'd just create a UIVew subclass called something like "CoolActionSheet" and programatically place the buttons on there. Then, when you press the buttons it triggers a delegate method in a protocol which will be implemented in your main view controller so do something.
To show and hide the action picker use UIView animations in the CoolActionSheet class like so:
-(void)showSheet {
NSLog(#"Showing sheet...");
//Set the x/y position of the action sheet to JUST off-screen
CGFloat xPos = parentView.frame.origin.x;
CGFloat yPos = parentView.frame.size.height+kActionSheetHeight;
[self setFrame:CGRectMake(xPos, yPos, kActionSheetWidth, kActionSheetHeight)];
/*Here is where you would add your other UI objects such as buttons
and set their #selector to a method in your CoolActionSheet protocol. You could then implement this delegate method in
your main view controller to carry out a custom action. You might also want to add a background image to the view or something else.
For example: */
UIButton *coolButton = [[UIButton alloc] initWithFrame:buttonDimensions];
[coolButton addTarget:self action:#selector(didDismissActionSheet) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:coolButton];
[self.parentView addSubview:self.view];
//Slide the sheet up from the bottom of the screen
[UIView animateWithDuration:0.2 animations:^(void) {
//Slide banner in from left to right
[self setFrame:CGRectMake(0, yPos-kActionSheetHeight, kActionSheetWidth, kActionSheetHeight)];
}];
}
And to hide:
-(void)hideSheet {
NSLog(#"Hiding");
CGFloat xPos = parentView.frame.origin.x;
CGFloat yPos = parentView.frame.size.height+kActionSheetHeight;
[UIView animateWithDuration:0.2 animations:^(void) {
[self setFrame:CGRectMake(xPos, yPos, 320, 65)];
}completion:^(BOOL finished) {
[self removeFromSuperview]; //Clean up
}];
}
You may also want to grey-out the parent view. Again, in the CoolActionSheet.m:
-(void)shadeParentView {
UIView *shadedView = [[UIView alloc] initWithFrame:CGRectMake(, 0, 320, 480)];
[shadedView addGestureRecognizer:gestureRecognizer];
[shadedView setBackgroundColor:[UIColor blackColor]];
[shadedView setAlpha:0.0];
[self addSubview:shadedView];
[UIView animateWithDuration:0.5 animations:^{
[shadedView setAlpha:0.5];
}];
}
You would need to set your parentView to the view controller's view. So, to call the action sheet in your main view controller you would:
CoolActionSheet *coolSheet = [[CoolActionSheet alloc] init];
[coolSheet setParentView:self.view];
[coolSheet setSheetDelegate:self]; //set the delegate to implement button press methods in this view controller
This might seem a bit long-winded, but it's a good MVC pattern to separate it out into another view class like this. And you now have a custom class that you can just import into any other project and it'll work!
I haven't had a chance to test out this specific code, but the whole approach is good. Points to take away from this:
Use a custom UIView class
Implement delegate methods to execute tasks in your main view controller when a button is pressed in your subview.
Implement a good MVC structure to avoid spaghetti code.
Let me know if this helps :)
Try This:
[actionSheet showInView:self.view.window];

How to decrease the width of a frame of an UIImage gradually without distorting it?

I think this is a very basic question, but I am struggling with this one.
I have a screenshot (an UIImage) which I put into an UIView (called screenShotView in my sample below). I want to get rid of this screenShotView by gradually revealing what is behind this screenShotView. Right now my screenShotView SQUEEZES to the left, but I would like its FRAME to become less and less until the screenShotView is no longer seen (without Squeezing).
This is my code. If I did the same transformation with an UITextView (instead of an UIImage) it would work exactly how I would like it to behave (without transformation).
Perhaps I don't get the concept of framing UIImages?
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:10];
[screenShotView setFrame:CGRectMake(0, 0, 0, 480)];
[UIView commitAnimations];
And this is how it looks like in the middle of the animation:
And this is how I would like it to look like in the middle of the animation:
This is the code updated to Codo's suggestions (see below), with the result that I have no animation anymore. The blue screen simply pops up once the button is pressed. I guess that I am doing something wrong with adding the subviews -- the problem appears to be that no subviews are added and can therefore not disappear:
-(IBAction)showNextText
{
screenShotView = [[UIImageView alloc] initWithImage:[self screenshot]];
[screenShotView setFrame:CGRectMake(0, 0, 320, 480)];
[screenShotScrollView setFrame:CGRectMake(0, 0, 320, 480)];
[self.view addSubview:screenShotScrollView];
[screenShotScrollView addSubview:screenShotView];
screenShotScrollView.scrollEnabled = NO;
[self setUpNextText];
[self removeOldText];
}
-(void)setUpNextText
{
NSString* secondText = #"This is the second text shown if the user clicks next.";
textView.text = secondText;
textView.textColor = [UIColor redColor];
textView.backgroundColor = [UIColor blueColor];
}
-(IBAction)removeOldText{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5];
[screenShotScrollView setFrame:CGRectMake(0,0,320,480)];
[UIView commitAnimations];
}
Answer to question
It's actually very simple: I've made a sample app to get the star wars(just calling it here) transition working. For simplicity I'll just call the two views firstView and secondView. firstView is shown (would be your screenshot) and secondView will slide in from the left. I've put a button on each view to animate the transition, which is wirde to doTransition. The important part is to set the sliding in view's properties clipsToBounds = YES and autoresizesSubviews = NO. That's it. I'll post some screenshots.
- (void)viewDidLoad
{
[super viewDidLoad];
secondView.frame = CGRectMake(0, 0, 0, 480);
secondView.clipsToBounds = YES;
secondView.autoresizesSubviews = NO;
[self.view addSubview:firstView];
[self.view addSubview:secondView];
}
- (IBAction)doTransition
{
[UIView animateWithDuration:1.0
animations:^{
self.secondView.frame = CGRectMake(0,
0,
320,
480);
}];
}
Research on page curl
I did some research on the page turn / curl effect. Mainly this is all present in iOS, with little effort you can create the iBook page turn effect, but it's accessing private methods and classes. I still encourage anyone to have a look at it, cause it might some day be opened.
Apple's iBooks Dynamic Page Curl - Demo App by Steven Troughton-Smith
Leaves - An App with a custom page curl by Tom Brow, tried, compiled and looks nice!
App Store-safe Page Curl animations - Article on Tom Brow's Leaves App which has been branched (twoPages) by the author Ole Begemann
Implementing iBooks page curling using a conical deformation algorithm - With a MacOS Demo App, very professional and advanced, though not an option for a quick shot still inspiring. Download the App!
The anatomy of a page curl - Mathematical approach
I guess you have to put your upper view into a UIScrollView. Then you set the content size to be the same as the size of the UIScrollView and disable scrolling.
Next you do your original animation (setFrame) on the UIScrollView.
Basically, you then use the UIScrollView to introduce a separate coordinate system for the inner view. When the outer view (the scroll view) is made smaller, it will not distort the inner view, but clip it.
CGRect fillRect = self.view.bounds;
leftImageView.clipsToBounds = YES;
leftImageView.contentMode = UIViewContentModeTopLeft;
leftImageView.frame = fillRect;
rightImageView.clipsToBounds = YES;
rightImageView.contentMode = UIViewContentModeTopRight;
rightImageView.frame = CGRectMake(fillRect.size.width, 0, 0, fillRect.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:3];
leftImageView.frame = CGRectMake(0, 0, 0, fillRect.size.height);
rightImageView.frame = fillRect;
[UIView commitAnimations];
Don't animate the frame but the center. See the documentation here.
Also, if you only need iOS 4 compatibility, use -animateWithDuration:animations:
[UIView animateWithDuration:10
animations:^{ screenShotView.center = CGPointMake(x, y) } ];
I'm not sure I fully understand how you want your view to disappear.
If it's supposed to become more and more transparent, use the following code (instead of setFrame):
[screenShotView setAlpha: 0.0f];
If it's supposed to become smaller and smaller (but keep its center), then try:
[screenShotView setFrame:CGRectMake(screenShotView.frame.x, screenShotView.frame,y, 0, 0)];

Can't interact with UITableView while animations are in progress

I'm trying to implement an animation that happens when a user taps one of my tableview cells. Basically, the animation is just a little label with text like "+5" or "+1" that appears, then moves upwards whilst fading (basically like points appear in video games as the user scores them).
In the tableView:didSelectRowAtIndexPath: implementation of my controller, I'm doing the following (paraphrased for simplicity here):
CGRect toastFrame = /* figure out the frame from the cell frame here */;
UILabel *toast = [[UILabel alloc] initWithFrame:toastFrame];
toast.text = [NSString stringWithFormat:#"+%d", 5];
toast.backgroundColor = [UIColor clearColor];
toast.userInteractionEnabled = NO; // hoped this would work but it doesn't
[tableView addSubview:toast];
[UIView
animateWithDuration:1.0
animations:^
{
toast.alpha = 0.0;
toast.transform = CGAffineTransformMakeTranslation( 0.0, -44.0 );
}
completion:^ (BOOL finished)
{
[toast removeFromSuperview];
}];
[toast release];
The toast is appearing nicely and looks great. The problem is that until the animation completes, the tableview stops receiving touch events. This means that for one second after tapping a cell in the tableview, you can't tap any other cells in the tableview.
Is there a way to stop this from happening and allow the user to keep interacting with the tableview as if the animations weren't happening at all?
Thanks in advance for any help with this.
Another option may be to use animateWithDuration:delay:options:animations:completion: (untested, from the top of my head)
Take a look at the options parameter and the possible flags, defined by UIViewAnimationOptions. Included there is a flag called UIViewAnimationOptionAllowUserInteraction. This could be a solution, maybe you should try it out!
Have you tried doing it the other way? For example, after adding toast as a subview, you can do something like this:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve: UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration: 1.0];
toast.alpha = 0.0;
toast.frame.origin.y -= 44.0;
[toast performSelector:#selector(removeFromSuperview) withObject: nil afterDelay: 1.0];
[UIView commitAnimations];
and then release toast. You can try it this way and see if it works.

iPhone UIView Animation Disables UIButton Subview

So I've got a problem with buttons and animations. Basically, I'm animating a view using the UIView animations while also trying to listen for taps on the button inside the view. The view is just as large as the button, and the view is actually a subclass of UIImageView with an image below the button. The view is a subview of a container view placed in Interface Builder with user interaction enabled and clipping enabled. All the animation and button handling is done in this UIImageView subclass, while the startFloating message is sent from a separate class as needed.
If I do no animation, the buttonTapped: message gets sent correctly, but during the animation it does not get sent. I've also tried implementing the touchesEnded method, and the same behavior occurs.
UIImageView subclass init (I have the button filled with a color so I can see the frame gets set properly, which it does):
- (id)initWithImage:(UIImage *)image {
self = [super initWithImage:image];
if (self != nil) {
// ...stuffs
UIButton *tapBtn = [UIButton buttonWithType:UIButtonTypeCustom];
tapBtn.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[tapBtn addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
tapBtn.backgroundColor = [UIColor cyanColor];
[self addSubview:tapBtn];
self.userInteractionEnabled = YES;
}
return self;
}
Animation method that starts the animation (if I don't call this the button works correctly):
- (void)startFloating {
[UIView beginAnimations:#"floating" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:10.0f];
self.frame = CGRectMake(self.frame.origin.x, -self.frame.size.height, self.frame.size.width, self.frame.size.height);
[UIView commitAnimations];
}
So, to be clear:
Using the UIView animation effectively disables the button.
Disabling the animation causes the button to work.
The button is correctly sized and positioned on screen, and moves along with the view correctly.
This resolves the issue:
[UIView animateWithDuration:20 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
...
The animation is just eye candy. The animation lags behind the actual movement of the view. The button is already at the destination point when the animation starts. You just see a movie of the view/button moving.
If you want a button to be clickable during the animation, you'll have to make the animation yourself.
... was experiencing this same problem because my code was doing one large animation per block. I made an NSTimer based solution, like the one suggested above, and it worked... yet the movement was jerky (unless I inserted animation within every timer event trigger).
So, since animation was required anyway, I found a solution which requires no timer. It animates only a short distance and thus the button click is still accurate, with only a small error which is my case is very unnoticeable in the UI, and can be reduced depending on your params.
Note below that the error at any given time is < 15.0, which can be reduced for more accuracy depending on your animation speed requirements. You can also reduce the duration time for more speed.
- (void)conveyComplete:(UIView*)v
{
[self convey:v delay:0];
}
- (void)convey:(UIView*)v delay:(int)nDelay
{
[UIView animateWithDuration:.5
delay:nDelay
options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
animations: ^
{
CGRect rPos = v.frame;
rPos.origin.x -= 15.0;
v.frame = rPos;
}
completion: ^(BOOL finished)
{
[self conveyComplete:v];
}];
}

iPhone Curl Left and Curl Right transitions

I am looking for a way to do a UIViewAnimationTransitionCurlUp or UIViewAnimationTransitionCurlDown transition on the iPhone but instead of top to bottom, do it from the left to right (or top/bottom in landscape mode). I've seen this asked aroud the internet a few times but none sems to get an answer. However I feel this is doable.
I have tried changing the View's transform and the view.layer's transform but that didn't affect the transition. Since the transition changes when the device changes orientation I presume there is a way to fool the device to use the landscape transition in portrait mode and vice versa?
It's possible to do curls in any of the four directions by using a container view. Set the container view's transformation to the angle you want and then do the curl by adding your view to the container view, not your app's main view which does not have a transformed frame:
NSView* parent = viewController.view; // the main view
NSView* containerView = [[[UIView alloc] initWithFrame:parent.bounds] autorelease];
containerView.transform = CGAffineTransformMakeRotation(<your angle here, should probably be M_PI_2 * some integer>);
[parent addSubview:containerView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:containerView cache:YES];
[containerView addSubview:view];
[UIView commitAnimations];
I actually managed to achieve this effect by changing the orientation of my UIViewController. The strange thing is, I had my controller nesten in another one when it wasn't working, but when I set him as the immediate view controller, it worked.
Code that does it:
In a UIViewController that is the main view controller in my app delegate and only allows landscape orientation (as you see in the 2nd method below) I have the following:
-(void)goToPage:(int)page flipUp:(BOOL)flipUp {
//do stuff...
// start the animated transition
[UIView beginAnimations:#"page transition" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:flipUp ? UIViewAnimationTransitionCurlUp : UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
//insert your new subview
//[self.view insertSubview:currentPage.view atIndex:self.view.subviews.count];
// commit the transition animation
[UIView commitAnimations];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
I also struggled with this. To get the curl to come from the right or left you can create an intermediate view and transform it. So, let's say the view you're transitioning (myView) is a child of the main window (parentView):
-parentView
-->myView
You will insert an intermediate view in between (easily done in Interface Builder):
-parentView
-->containerView
--->myView
Then, use the following code to flip the container 90 deg left and the transitioned view 90 deg right:
containerView.transform = CGAffineTransformMakeRotation(-M_PI_2);
myView.transform = CGAffineTransformMakeRotation(M_PI_2);
myView will still appear upright to the user but the transition will think it's applied at 90 degrees from the left.
Note that depending on how auto-scaling your views are, you might have to fix the frame sizes after applying the transform, eg
containerView.frame = CGRectMake(0.0, 0.0, 768.0, 1024.0);
myWebView.frame = CGRectMake(0.0, 0.0, 768.0, 1024.0);
Hope this helps. The is the closest you can get to UIViewAnimationTransitionCurlLeft and UIViewAnimationTransitionCurlRight.
I tried the solution of fluXa on iOS5 (So I had to use [UIView trans......]) but it didn't work: the curl still went up or downwards. Apparently the transition now don't take the transform of the view into account. So in case someone else wants to do the same trick on iOS5, the solution is to add another container in between and animate the transition from there.
Here is my code, which is a bit specific since I want to curl 'up' to the left, but with the lower corner curling. As if I am tearing a page out of a note book.
UIView* parent = self.view; // the main view
CGRect r = flipRectSize(parent.bounds);
UIView* containerView = [[UIView alloc] initWithFrame:r];
CGAffineTransform t = CGAffineTransformMakeRotation(-M_PI_2);
t = CGAffineTransformTranslate(t, -80, -80);
containerView.transform = CGAffineTransformScale(t, -1, 1);
[parent addSubview:containerView];
UIView* container2 = [[UIView alloc] initWithFrame:r];
[containerView addSubview:container2];
UIImageView* v = [[UIImageView alloc] initWithFrame:r];
v.image = [UIImage imageWithCGImage:contents.CGImage scale:contents.scale orientation:UIImageOrientationLeftMirrored];
[container2 addSubview:v];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.001 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[UIView transitionWithView:container2
duration:DURATION_CURL_ANIMATION
options:UIViewAnimationOptionTransitionCurlUp
animations:^{
[v removeFromSuperview];
} completion:^(BOOL finished) {
if (completion) {
completion(finished);
}
[containerView removeFromSuperview];}];});
Notes:
I must admit that the affine transform translate (80,80) doesn't make sense in my mind, but it is necessary for iphone, probably won't work on iPad.
flipSizeRect flips the width and height of a rectangle (you already got that, right?)
the dispatch_after is necessary because I added the container and then want to remove a view from the hierarchy. If I leave out the dispatch nothing animates. My best guess is that we first need to let the system do a layout pass before we can animate a removal.
I don't think there is a way beyond writing a custom animation.
More importantly you probably shouldn't try to it. The curl up and curl down are part of the user interface grammar that tells the user that a view is being lifted up or put down over the existing view. It's supposed to be like a sticky note being put down and then removed. A left<->right curl will most likely be interpreted as the something like ripping a page out of a book. It will confuse users.
Whenever you find yourself trying to do something in the interface that the standard API doesn't do easily, you should ask yourself whether such a novel method will communicate something important to user and whether it is similar to the existing interface grammar. If not, then you shouldn't bother.
Unusual interfaces have an initial wow factor but they lead to frustration and errors in day-to-day use. They can also cause Apple to refuse your app.