翻转和缩放3D转换问题(iOS 7+)

我正在尝试构build卡片翻转和缩放的转换。 我已经在折纸 – 电影(less于1Mb)

正如你所看到的,同时应用了3个变换:1.将视图的中心移动到屏幕的中心2.缩放3. 3D旋转

我们可以分为两个阶段的animation:
阶段1:button缩放,移动并在侧面旋转(PI / 2弧度)。 在阶段1结束时button消失。
阶段2: toView (我的模态视图)旋转(从-PI / 2到0弧度),放大到正常大小,并将视图的中心移动到屏幕中心。 如果我们排除反弹 – 这是非常简单的转换。

但是在构build时遇到了一些问题:
我只是一个button,而不是整个视图。 这个button背后有一个背景。 所以,如果我应用CATransform3DMakeRotationbutton的一半消失 – 它与3D空间(Z轴)中的背景相交。 有没有办法在这里使用3DTransform?
2.屏幕上有一些文物。 我不知道他们来自哪里。

你可以检查结果电影 (3.8Mb)。 我放慢了电影中第二张卡片的animation。

这是我的这个animation的代码:

 func animateTransition(transitionContext: UIViewControllerContextTransitioning) { let container = transitionContext.containerView() let fromViewBig = transitionContext.viewForKey(UITransitionContextFromViewKey)! let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! // Converting button to UIImageView and hiding actual button let button = sourceViewController.view.viewWithTag(sourceViewController.buttonIndex)! UIGraphicsBeginImageContextWithOptions(button.bounds.size, false, 0.0) button.layer.renderInContext(UIGraphicsGetCurrentContext()) var img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext(); let fromView = UIImageView(frame: button.frame) fromView.image = img button.hidden = true container.addSubview(toView) container.addSubview(fromView) let duration = self.transitionDuration(transitionContext) // Add a perspective transform var transform = CATransform3DIdentity transform.m34 = -0.002 container.layer.sublayerTransform = transform //calculating "median" frame size - size of the frame in 1/2 of animation let medianX = (toView.frame.width + fromView.frame.width) / 2 let medianY = (toView.frame.height + fromView.frame.height) / 2 // at the midpoint of our animation final size of fromView should be equal to starting size of toView // initial scale transfor fo toView (it will appear in second half of animation) let initialToScaleTransform = CATransform3DMakeScale(medianX/toView.frame.width, medianY/toView.frame.height, 1.0) // final scale of fromView let finalFromScaleTransform = CATransform3DMakeScale(medianX/fromView.frame.width, medianY/fromView.frame.height, 1.0) let finalToScaleTransform = CATransform3DMakeScale(1.0, 1.0, 1.0) // our view is moving diring animation too let startCenter = fromView.center let endCenter = toView.center let midCenter = CGPoint(x: (startCenter.x + endCenter.x)/2, y: (startCenter.y + endCenter.y)/2) // flip the to VC halfway round - hiding it toView.layer.transform = CATransform3DRotate(initialToScaleTransform, CGFloat(-M_PI_2), 0.0, 1.0, 0.0) toView.center = midCenter // animate UIView.animateKeyframesWithDuration(duration, delay: 0, options: UIViewKeyframeAnimationOptions.allZeros, animations: { () -> Void in UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.5, animations: { () -> Void in fromView.layer.transform = CATransform3DRotate(finalFromScaleTransform, CGFloat(M_PI_2), 0.0, 1.0, 0.0) fromView.center = midCenter }) UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.5, animations: { () -> Void in toView.layer.transform = CATransform3DRotate(finalToScaleTransform, 0.0, 0.0, 1.0, 0.0) toView.center = endCenter }) }) { (finished) -> Void in transitionContext.completeTransition(!transitionContext.transitionWasCancelled()) } }