如何使用 CGAffineTransform Identity 进行 View Controller 转换

How do View Controller transitions happen with CGAfflineTransformIdentity

我一直在尝试在呈现另一个视图控制器时进行自定义转换,我以两种方式成功了。一种是使用 CGAfflineTransformIdentity,另一种是使用 CGAffineTransformMakeTranslation 推送 ViewController。

Apple 文档将 CGAfflineTransformIdentity 描述为单位单位矩阵。当我使用单位矩阵变换视图时,我的动画是如何发生的?

在实际数学中,当我将一些东西与单位矩阵相乘时,我得到了相同的矩阵。

那么 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)
    })
}

当我使用单位矩阵变换视图时我的动画是如何发生的

答案是,从技术上讲,使用单位矩阵转换视图没有任何作用。但是,将视图的变换设置为单位矩阵会撤消该视图上的任何现有变换。因此,如果它已缩放或旋转,您将有效地撤消该过渡。在您的情况下,这意味着您正在撤消将视图向上移动的平移变换,因此现在它回到原点。

这解释了为什么在您的动画块中您可以调用 toView.transform = CGAffineTransformIdentitytoView.transform = offScreenDownCGAffineTransformMakeTranslation(0, 0) 只是由零点翻译的恒等变换。

要证明恒等变换只是撤销初始变换,您可以将其连接到目标变换:

toView.transform = CGAffineTransformConcat(offScreenDown,CGAffineTransformIdentity)

正如预期的那样,这没有任何效果,因为恒等变换仅在计算中复制变换的内容:

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

意味着在你的动画块中 offScreenDown == CGAffineTransformIdentity == CGAffineTransformConcat(offScreenDown,CGAffineTransformIdentity) == CGAffineTransformConcat(CGAffineTransformIdentity,CGAffineTransformIdentity)

在 iOS 7 上,注意恒等变换很重要,因为它与动画过渡有关,因为我发现容器视图将变换应用于其子视图以确保它们处于正确的方向(因为容器实际上在一个新的 UIWindow 实例中)。这实际上在开发者论坛中提到过:

"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."