4

This has been asked before, but there is no sample code to be found on stackoverflow and no proper solutions as far as I'm aware. I have a solution, but it looks crap. I'd be grateful for any input and modifications to get a more realistic 3D door open / book cover animation.

Aim is to have an animation between UIViewControllers so that you get the effect as if you were opening a door or a book cover. ViewController 2 is static and in the background. Above it you place ViewController 1 which covers ViewController 2. The animation will open ViewController 1 (like a hardcover book) and reveal ViewController 2 (your first page so to say, or whatever is behind the door).

First thing to note is that you can't do this with an UINavigationController as it is difficult to overwrite the custom animations. A proper tutorial on how to set up our two ViewControllers can be found here: ViewController Animations

So once everything is setup, here is my custom animation which looks crap. It basically looks as if you are squeezing the door / cover of the book to the left. There is no 3D feel to it, I'm afraid. Any suggestions of how to make this better would be welcome:

-(void)openDoorTo:(UIViewController *)aController duration:(float)aDuration {


    [aController viewWillAppear:YES];
    [activeController viewWillDisappear:YES];

    [self.view insertSubview:aController.view belowSubview:activeController.view]; // so that it is below activeController

    [aController viewDidAppear:YES];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:aDuration];

    aController.view.transform = CGAffineTransformMakeTranslation(0,0);

    CATransform3D _3Dt = CATransform3DIdentity;
    _3Dt = CATransform3DTranslate(_3Dt, -320, 0, 0);
    _3Dt = CATransform3DRotate(_3Dt, M_PI * 1.5, 0.0, 1, 0.0);
    _3Dt = CATransform3DTranslate(_3Dt, 320, 0, 0);

    activeController.view.layer.transform = _3Dt;

    [UIView commitAnimations];

    [self performSelector:@selector(animationDone:) withObject:aController afterDelay:aDuration];


}

I think the main problem is that I don't really know how to handle CATransform3DTranslate and CATransform3DRotate.

Here are some posts on this, but I can't really see how to apply them to a 3D Door opener:

3D Door - but Axis in the middle

3D Unfolding

Community
  • 1
  • 1
n.evermind
  • 11,944
  • 19
  • 78
  • 122

1 Answers1

8

You have to apply a little trick to get 3D to work:

CATransform3D _3Dt = CATransform3DIdentity;
_3Dt.m34 = 1.0 / -1000;

This creates perspective transform. 1000 represents the distance from the viewer to the objects (you can experiment with this value to get a smooth look).

thirtydot
  • 224,678
  • 48
  • 389
  • 349
Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217
  • Thanks, but I only get the error message that _3Dtm34 is not defined. Where does the m34 come from? If I take it away, I also get an error (assigning to CATransform3D' from incompatible type double... sorry if this is obvious, but I don't know what to do with m34. – n.evermind Oct 07 '11 at 09:53
  • Sorry, there must be a dot between _3Dt.m34... silly question, sorry. – n.evermind Oct 07 '11 at 10:01
  • On a more substantial nature: The door is now opening to the inside of the room (or the book). How do I make it come out? I.e. like a book cover which comes towards you and does not go into the book. I tried to reverse the distance from viewer so that I'll get 1.0 / 1000 but that doesn't work. It just mutilates the animation completely. Thanks for your patience. – n.evermind Oct 07 '11 at 10:06
  • Oh dear, I suppose that was again a silly question. I reduced it to 1.0 / 500 and it now looks perfect. Thanks so much for your answer. Wasn't so difficult after all! – n.evermind Oct 07 '11 at 10:09
  • tnx animation works perfect, Could anybody tell me how to reverse this animation ? – Соёмбо Бат-Эрдэнэ Mar 24 '16 at 05:29
  • it may work switching the xxxTranslate() calls and reversing the angle in xxxRotate() to use -1.5. Not tested. – Martin Ullrich Mar 24 '16 at 10:43