I just did this code for a UIButton that "page turns" away when pressed, and I thought I'd share it with you in case anybody needs something similar. You could use this for example to make a book with turning pages. Anyway, have fun and if you have any comments, fire away!
Code:
- (IBAction) openButton:(id)sender {
UIButton *button = (UIButton *)sender;
// disable the button so it’s not pressed again during the animation
((UIView *)sender).userInteractionEnabled = NO;
// Set the CALayer anchorPoint to the left edge and
// translate the button to account for the new
// anchorPoint. In case you want to reuse the animation
// for this button, we only do the translation and
// anchor point setting once.
if (button.layer.anchorPoint.x != 0.0f) {
button.layer.anchorPoint = CGPointMake(0.0f, 0.5f);
button.center = CGPointMake(button.center.x – button.bounds.size.width/2.0f,
button.center.y);
}
// create an animation to hold the page turning
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.removedOnCompletion = NO;
transformAnimation.duration = 2.0f;
transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
// start the animation from the current state
transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
// this is the basic rotation by 90 degree along the y-axis
CATransform3D endTransform = CATransform3DMakeRotation(3.141f/2.0f,
0.0f,
-1.0f,
0.0f);
// these values control the 3D projection outlook
endTransform.m34 = 0.001f;
endTransform.m14 = -0.0015f;
transformAnimation.toValue = [NSValue valueWithCATransform3D:endTransform];
// Create an animation group to hold the rotation
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
// Set self as the delegate to receive notification when the animation finishes
theGroup.delegate = self;
theGroup.duration = 2.0;
// CAAnimation-objects support arbitrary Key-Value pairs, we add the UIView tag
// to identify the animation later when it finishes
[theGroup setValue:[NSNumber numberWithInt:button.tag] forKey:@”buttonTag”];
// Here you could add other animations to the array
theGroup.animations = [NSArray arrayWithObjects:transformAnimation, nil];
theGroup.removedOnCompletion = NO;
// Add the animation group to the layer
[button.layer addAnimation:theGroup forKey:@"flipButtonOpen"];
// Get the tag from the animation, we use it to find the
// animated UIView
NSNumber *tag = [theAnimation valueForKey:@"buttonTag"];
// Find the UIView with the tag and do what you want
for (UIView *subview in contents.subviews) {
Wouldn't it be a whole lot easier and faster to put the button in it's unique UIView in IB and then use one of the predefined view transition animations?
First, there's no need to put the button in a UIView because UIButton is a subclass of UIView, you can use the predefined view transitions straight out of the box. Second, none of the predefined transitions do this kind of "book page turn" transition: page flip from right or left turns the page along the center vertical axis, and page curl is more akin to tearing a page off a calendar. If you want to go beyond the predefined transitions, you have to code things yourself, and that's what I wanted and did.
First, there's no need to put the button in a UIView because UIButton is a subclass of UIView, you can use the predefined view transitions straight out of the box. Second, none of the predefined transitions do this kind of "book page turn" transition: page flip from right or left turns the page along the center vertical axis, and page curl is more akin to tearing a page off a calendar. If you want to go beyond the predefined transitions, you have to code things yourself, and that's what I wanted and did.
Thank you fiftysixty. This is nice to share. Perhaps the forum moderator could move this thread to "Tutorial" section.
I just did this code for a UIButton that "page turns" away when pressed, and I thought I'd share it with you in case anybody needs something similar. You could use this for example to make a book with turning pages. Anyway, have fun and if you have any comments, fire away!
Code:
- (IBAction) openButton:(id)sender {
UIButton *button = (UIButton *)sender;
// disable the button so it’s not pressed again during the animation
((UIView *)sender).userInteractionEnabled = NO;
// Set the CALayer anchorPoint to the left edge and
// translate the button to account for the new
// anchorPoint. In case you want to reuse the animation
// for this button, we only do the translation and
// anchor point setting once.
if (button.layer.anchorPoint.x != 0.0f) {
button.layer.anchorPoint = CGPointMake(0.0f, 0.5f);
button.center = CGPointMake(button.center.x – button.bounds.size.width/2.0f,
button.center.y);
}
// create an animation to hold the page turning
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.removedOnCompletion = NO;
transformAnimation.duration = 2.0f;
transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
// start the animation from the current state
transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
// this is the basic rotation by 90 degree along the y-axis
CATransform3D endTransform = CATransform3DMakeRotation(3.141f/2.0f,
0.0f,
-1.0f,
0.0f);
// these values control the 3D projection outlook
endTransform.m34 = 0.001f;
endTransform.m14 = -0.0015f;
transformAnimation.toValue = [NSValue valueWithCATransform3D:endTransform];
// Create an animation group to hold the rotation
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
// Set self as the delegate to receive notification when the animation finishes
theGroup.delegate = self;
theGroup.duration = 2.0;
// CAAnimation-objects support arbitrary Key-Value pairs, we add the UIView tag
// to identify the animation later when it finishes
[theGroup setValue:[NSNumber numberWithInt:button.tag] forKey:@”buttonTag”];
// Here you could add other animations to the array
theGroup.animations = [NSArray arrayWithObjects:transformAnimation, nil];
theGroup.removedOnCompletion = NO;
// Add the animation group to the layer
[button.layer addAnimation:theGroup forKey:@"flipButtonOpen"];
// Get the tag from the animation, we use it to find the
// animated UIView
NSNumber *tag = [theAnimation valueForKey:@"buttonTag"];
// Find the UIView with the tag and do what you want
for (UIView *subview in contents.subviews) {
Feel free to download the project and use it in your Apps as you wish.
Mikko,
Hello and thanks for your code! I am trying to rotate the button counterclockwise along the y-axis but it doesn't seem to be working... Any idea why? I understand that I should just need to change the sign of the y-axis vector, but it still has not changed direction. Here is my code:
//set the anchor point to the right side of the button(334 is the width)
if (button.layer.anchorPoint.x != 0.0f) {
button.layer.anchorPoint = CGPointMake(1.0f, 0.5f);
button.center = CGPointMake(334.0f, button.center.y);
}
// create an animation to hold the page turning
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.removedOnCompletion = NO;
transformAnimation.duration = 1.5f;
transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseO ut];
// start the animation from the current state
transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
// this is the basic rotation by 90 degree along the y-axis
CATransform3D endTransform = CATransform3DMakeRotation(3.14, 0.0f, 1.0f, 0.0f);
Hi I need animation of 180ş of rotation, that is after the animation the view should be of mirror like appearance. I had change the degree to 180ş in your code but the animation stops in the middle say like 120ş of angle. How to rotation it to 180ş
plz help me.
Nope, didnt figure it out. Also, on the device, I am getting a "flicker" when I remove the subview. I have tried numerous things and it just will not go away.
I don't know whether you can act on the splash screen like that. I don't think you can.
One work-around might be to have a view controller that shows nothing else than your splash screen PNG (i.e. looks exactly like your splash screen) load first. Then, after the wanted interval, you can move from that fake view controller to your real first view controller and have that transmission animated. Does that make sense?
Hope this helps.
Cheers,
Bob
__________________ We are God’s middle children, according to Tyler Durden, with no special place in history and no special attention.