0

I have been trying to make my custom transition while presenting another view controller and I succeeded in two ways. One is through using CGAfflineTransformIdentity and another just by pushing the ViewController using CGAffineTransformMakeTranslation.

The Apple documentation describes CGAfflineTransformIdentity as a unit identity matrix. How does my animation happen while I transform my view with identity matrix?

In real math while I multiply some thing with unit matrix I get the same matrix as a result.

So how does the transition really happen with CGAfflineTransformIdentity?

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    let container = transitionContext.containerView()
    let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
    let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!

    let offScreenUp = CGAffineTransformMakeTranslation(0, -container.frame.size.height )
    let offScreenDown = CGAffineTransformMakeTranslation(0, 0)

    toView.transform = offScreenUp

    container.addSubview(fromView)
    container.addSubview(toView)

    let duration = self.transitionDuration(transitionContext)       
    UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.8, options: nil, animations: {
          toView.transform = CGAffineTransformIdentity
         //toView.transform = offScreenDown
        }, completion: { finished in
         // tell our transitionContext object that we've finished animating
         transitionContext.completeTransition(true)
    })
}
Daniel Galasko
  • 23,617
  • 8
  • 77
  • 97
LC 웃
  • 18,888
  • 9
  • 57
  • 72

1 Answers1

1

How does my animation happen while I transform my view with identity matrix

The answer to that is that technically, transforming a view with the identity matrix does nothing. However, setting the transform of your view to the identity matrix would undo any existing transform on that view. So if it had been scaled or rotated you would effectively undo that transition. In your case this means that you are undoing the translation transform that moved your view up so now it settles back to the origin.

This explains why in your animation block you can call either toView.transform = CGAffineTransformIdentity OR toView.transform = offScreenDown. CGAffineTransformMakeTranslation(0, 0) is just the identity transform translated by zero points.

To prove that the identity transform is only undoing the initial transform you could concatenate it to your destination transform:

toView.transform = CGAffineTransformConcat(offScreenDown,CGAffineTransformIdentity)

As expected this has no effect since the identity transform only copies the contents of the transforms in a calculation:

The identity transform is a data transformation that copies the source data into the destination data without change (Wikipedia)

Meaning that inside your animation block offScreenDown == CGAffineTransformIdentity == CGAffineTransformConcat(offScreenDown,CGAffineTransformIdentity) == CGAffineTransformConcat(CGAffineTransformIdentity,CGAffineTransformIdentity)

On iOS 7 its important to be mindful of identity transform as it pertains to animated transitions since I have found the container view applies a transform to its subviews to make sure they are in the correct orientation (since the container is actually inside a new UIWindow instance). This was actually mentioned in the Developer forums:

"For custom presentation transitions we setup an intermediate view between the window and the windows rootViewController's view. This view is the containerView that you perform your animation within. Due to an implementation detail of auto-rotation on iOS, when the interface rotates we apply an affine transform to the windows rootViewController's view and modify its bounds accordingly. Because the containerView inherits its dimensions from the window instead of the root view controller's view, it is always in the portrait orientation."

Daniel Galasko
  • 23,617
  • 8
  • 77
  • 97
  • i have some questions with your answer lets assume "***setting the transform of your view to the identity matrix would undo any existing transform on that view*** " But does that really match with the real matrix multiplication. if i do analogy with the real matrix multiplication then this is absolutely true **toView.transform = CGAffineTransformConcat(offScreenDown,CGAffineTransformIdentity)** Thanks for your answer.It really is great!!! – LC 웃 Apr 03 '15 at 04:17
  • @anishparajuli reassignment is not matrix multiplication at all technically. Calling A=B, then A=X does not mean you have performed matrix multiplication it means you have undone 'B' and applied 'X' :) – Daniel Galasko Apr 07 '15 at 08:07
  • Actually i didn't understand for the first time and wrote down a comment.After i did..i rewarded you the bounty :) ...Really Thanks man! – LC 웃 Apr 07 '15 at 15:05
  • Great to hear I could help! Any chance you could accept my answer? Have a great day @anishparajuli – Daniel Galasko Apr 07 '15 at 15:16