当我使用自定义UIViewControllerAnimatedTransitioning进行从AViewController到BViewController的自定义转换时,它使用Cubic Animation按预期执行,但是当我尝试使用默认的iOS演示文稿时,就像从BViewController转换到CViewController的模式一样,它根本没有动画。
这是第一次转换的代码:
class CubeTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
private var direction: Direction!
convenience init(direction: Direction) {
self.init()
self.direction = direction
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 1
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let fromView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else {
return
}
toView.frame = fromView.frame
containerView.backgroundColor = UIColor.white
let fromViewIntialTransform = fromView.layer.transform
fromView.layer.anchorPointZ = -((fromView.frame.size.width) / 2)
var transform: CATransform3D = CATransform3DIdentity
transform.m34 = -1.0 / 1000
transform = CATransform3DTranslate(transform, 0, 0, (fromView.layer.anchorPointZ))
fromView.layer.transform = transform
containerView.addSubview(fromView)
toView.alpha = 1
fromView.alpha = 1
let toViewIntialTransform = toView.layer.transform
toView.layer.anchorPointZ = -((toView.frame.size.width) / 2)
transform = CATransform3DIdentity
transform.m34 = -1.0 / 1000
transform = CATransform3DTranslate(transform, 0, 0, (toView.layer.anchorPointZ))
toView.layer.transform = transform
containerView.insertSubview(toView, belowSubview:fromView)
// transform toView to it's begining position
switch direction {
case .left: // t angle x y z
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(-Double.pi/2), 0, 1, 0)
case .right:
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(Double.pi / 2), 0, 1, 0)
case .up:
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(Double.pi/2), 1, 0, 0)
case .down:
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(-Double.pi/2), 1, 0, 0)
default:
break
}
UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0.0, options: UIViewAnimationOptions(), animations: {
// Animate toView to go to fromView initial position,
// And the fromView to go to a new position
switch self.direction {
case .left: // t angle x y z
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(Double.pi / 2), 0, 1, 0)
fromView.layer.transform = CATransform3DRotate((fromView.layer.transform), CGFloat(Double.pi / 2), 0, 1, 0)
case .right:
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(-Double.pi / 2), 0, 1, 0)
fromView.layer.transform = CATransform3DRotate((fromView.layer.transform), CGFloat(-Double.pi / 2), 0, 1, 0)
case .up:
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(Double.pi/2), 1, 0, 0)
fromView.layer.transform = CATransform3DRotate((fromView.layer.transform), CGFloat(Double.pi / 2), 1, 0, 0)
case .down:
toView.layer.transform = CATransform3DRotate((toView.layer.transform), CGFloat(-Double.pi/2), 1, 0, 0)
fromView.layer.transform = CATransform3DRotate((fromView.layer.transform), CGFloat(-Double.pi / 2), 1, 0, 0)
default:
break
}
}, completion: {(value: Bool) in
fromView.layer.transform = fromViewIntialTransform
toView.layer.transform = toViewIntialTransform
fromView.layoutSubviews()
toView.layoutSubviews()
// This undo the transition if it's cancelled
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
})
}
}
当我使用另一个转换来执行从A到B的segue时,事情变得更加奇怪,从B到C的转换开始再次起作用。
第二次转型:
class PopTransition: NSObject, UIViewControllerAnimatedTransitioning {
let duration = 0.3
var originFrame = CGRect.zero
var presenting = true
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
let toView = transitionContext.view(forKey: .to)!
let detailView = presenting ? toView : transitionContext.view(forKey: .from)!
let initialFrame = presenting ? originFrame : detailView.frame
let finalFrame = presenting ? detailView.frame : originFrame
let xScaleFactor = presenting
? initialFrame.width / finalFrame.width
: finalFrame.width / initialFrame.width
let yScaleFactor = presenting
? initialFrame.height / finalFrame.height
: finalFrame.height / initialFrame.height
let scaleTransform = CGAffineTransform(scaleX: xScaleFactor, y: yScaleFactor)
if presenting {
detailView.transform = scaleTransform
detailView.center = CGPoint(
x: initialFrame.midX,
y: initialFrame.midY)
}
containerView.addSubview(toView)
containerView.bringSubview(toFront: detailView)
UIView.animate(
withDuration: duration,
delay: 0.0,
animations: {
detailView.transform = self.presenting ? .identity : scaleTransform
detailView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
},
completion:{_ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
)
}
}
答案 0 :(得分:1)
您正在修改 toView.layer.anchorPointZ 和 fromView.layer.anchorPointZ ,因此当从B到C的转换即将发生时, anchorPointZ < / strong>搞砸了。
尝试保存并重置,就像使用 fromViewIntialTransform 和 toViewIntialTransform 一样。