Page Flip: Difference between revisions

From iPhone Development Wiki
(+ proper syntax highlighting)
 
Line 5: Line 5:
Aight, so to flip a view open, we take the view, and rotate it using core animation by 90 degrees in y direction around the left side of it. All makes sense right? So, get a UIView as a container and add anything you want to flip onto it.
Aight, so to flip a view open, we take the view, and rotate it using core animation by 90 degrees in y direction around the left side of it. All makes sense right? So, get a UIView as a container and add anything you want to flip onto it.


<source lang=objc>
   -(void)pageOpen {
   -(void)pageOpen {
         //Make sure the container is visible and remove any other previous animations from it
         //Make sure the container is visible and remove any other previous animations from it
Line 46: Line 47:
         [uiv_container.layer addAnimation:ag_group forKey:@"Flip View"];
         [uiv_container.layer addAnimation:ag_group forKey:@"Flip View"];
   }
   }
</source>


==Flipping Closed==
==Flipping Closed==
Now, we have the page up, so next we need to rotate it down back to flat. Rotate it another 90 degrees in the Y direction, this time we need to rotate on the right side of it (so all the text looks right when its rotating down. This gives the illusion that there is a front and a back to the view.
Now, we have the page up, so next we need to rotate it down back to flat. Rotate it another 90 degrees in the Y direction, this time we need to rotate on the right side of it (so all the text looks right when its rotating down. This gives the illusion that there is a front and a back to the view.


<source lang=objc>
   -(void)pageFlip {
   -(void)pageFlip {
   NSLog(@"page opening");
   NSLog(@"page opening");
Line 81: Line 84:
     [uiv_container.layer addAnimation:ag_group forKey:@"Flip View"];
     [uiv_container.layer addAnimation:ag_group forKey:@"Flip View"];
   }
   }
</source>


==Animation Did Stop==
==Animation Did Stop==
Finally, we need something to manage everything when the animation ends. So here we tell it to run the the page flip after the page open finishes
Finally, we need something to manage everything when the animation ends. So here we tell it to run the the page flip after the page open finishes
   
   
<source lang=objc>
   - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
   - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
   NSLog(@"animation did stop");
   NSLog(@"animation did stop");
Line 100: Line 105:
   }
   }
   }
   }
</source>


==Conclusion==
==Conclusion==
Hopefully this gets you on the correct path for a flip animation. Good luck. Need, any help? Let me know!
Hopefully this gets you on the correct path for a flip animation. Good luck. Need, any help? Let me know!

Latest revision as of 06:16, 21 January 2014

Introduction

Ok, so maybe you need a page flip animation. There are lots of UIView default animations, that look really good, but my UI designed really busted me and was like "NO, I WANT A BARN DOOR FLIP". Anyway, there isn't a default way that I could find to do this. So I had to take a dive into core animation land and dig deep.

Flipping Open

Aight, so to flip a view open, we take the view, and rotate it using core animation by 90 degrees in y direction around the left side of it. All makes sense right? So, get a UIView as a container and add anything you want to flip onto it.

   -(void)pageOpen {
        //Make sure the container is visible and remove any other previous animations from it
        [uiv_container.layer removeAllAnimations];
        [uiv_front setHidden:NO];
        [uiv_container setUserInteractionEnabled:NO];
       
        //Sets the anchor point to the middle of the left side
        uiv_container.layer.anchorPoint = CGPointMake(0.0f,0.5f);
       
        //Set up a new animation to describe the transform
        CABasicAnimation *ba_animation = [CABasicAnimation animationWithKeyPath:@"transform"];
       
        ba_animation.removedOnCompletion = NO;
        
        //This is the time it takes for the animation to complete, here its 2 seconds
        ba_animation.duration = 2.0;
         
        //Using different timing functions will change the animation speed at different points. Ex: kCAMediaTimingFunctionEaseIn
        ba_animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
        
        //Start from the identity matrix. If you haven't every done 3D programming, the Identity matrix is basically the normal matrix of anything
        ba_animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
        
        //Set up the end matrix. Here we are setting it to 90 degrees in the Y direction
        CATransform3D t_end = CATransform3DMakeRotation(M_PI/2, 0.0, -1.0, 0.0);
        
        //This value controls the size of the end, modifying it like this makes it get bigger, making it more like a 3D rotation
        t_end.m14 = -0.001f;
        
        ba_animation.toValue = [NSValue valueWithCATransform3D:t_end];
       
        //Add the animation to an animation group, this lets us track the animation as it finishes
        CAAnimationGroup *ag_group = [CAAnimationGroup animation];
        ag_group.delegate = self;
        ag_group.duration = 2.0;
        
        [ag_group setValue:[NSNumber numberWithInt:1] forKey:@"Animation Tag"];
        ag_group.animations = [NSArray arrayWithObjects:ba_animation, nil];
        
        [uiv_container.layer addAnimation:ag_group forKey:@"Flip View"];
   }

Flipping Closed

Now, we have the page up, so next we need to rotate it down back to flat. Rotate it another 90 degrees in the Y direction, this time we need to rotate on the right side of it (so all the text looks right when its rotating down. This gives the illusion that there is a front and a back to the view.

   -(void)pageFlip {
   	NSLog(@"page opening");
   	 
   	uiv_container.layer.anchorPoint = CGPointMake(1.0f,0.5f);
   	
   	CABasicAnimation *ba_animation = [CABasicAnimation animationWithKeyPath:@"transform"];
   
   	ba_animation.removedOnCompletion = NO;
   	ba_animation.duration = 2.0;
   	ba_animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
   	
   	//This time we need to start from the position where the frame is 90 degrees rotated
   	CATransform3D t_start = CATransform3DMakeRotation(M_PI/2, 0.0, -1.0, 0.0);
   
    	//Need the opposite of the previous value so that the edge is sized correctly from the beginning
    	t_start.m14 = 0.001f;
   	
   	ba_animation.fromValue = [NSValue valueWithCATransform3D:t_start];
   
   	//Now rotate it down to the identity matrix
    	ba_animation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
   
   	CAAnimationGroup *ag_group = [CAAnimationGroup animation];
   	ag_group.delegate = self;
   	ag_group.duration = 2.0;
   
   	[ag_group setValue:[NSNumber numberWithInt:2] forKey:@"Animation Tag"];
   	ag_group.animations = [NSArray arrayWithObjects:ba_animation, nil];
   
    	[uiv_container.layer addAnimation:ag_group forKey:@"Flip View"];
   }

Animation Did Stop

Finally, we need something to manage everything when the animation ends. So here we tell it to run the the page flip after the page open finishes

   - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
   	NSLog(@"animation did stop");
       // Get the tag from the animation, we use it to find the
       // animated UIView
       NSNumber *tag = [theAnimation valueForKey:@"Animation Tag"];
   	if([tag intValue] == 1) {
   		uiv_front.hidden = YES;
   		[uiv_front removeFromSuperview];
   		[self.view addSubview:uiv_back];
   		uiv_back.hidden = NO;
   		[self pageOpen];
   	} if([tag intValue] == 2) {
   		
   	}
   }

Conclusion

Hopefully this gets you on the correct path for a flip animation. Good luck. Need, any help? Let me know!