自定义UIViewController转换不会执行下一个动画

时间:2017-11-15 18:47:04

标签: ios swift animation

当我使用自定义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)
        }
        )
    }
}

1 个答案:

答案 0 :(得分:1)

您正在修改 toView.layer.anchorPointZ fromView.layer.anchorPointZ ,因此当从B到C的转换即将发生时, anchorPointZ < / strong>搞砸了。

尝试保存并重置,就像使用 fromViewIntialTransform toViewIntialTransform 一样。