过渡动画就像在Snapchat中一样

时间:2016-09-21 17:56:45

标签: ios iphone swift

我正在尝试像在Snapchat中一样进行过渡动画。当用户向下切换屏幕时,视频会继续顺畅播放。

enter image description here

容器中的图像执行转换时

enter image description here

我正在添加FromViewController视图作为转换容器子视图。 (FromViewController使用AVPlayerLayer播放视频)

但是在容器层(我添加了FromViewController)的视频转换滞后时,它无法顺利播放。

    containerView!.addSubview((fromVC?.view)!)

我发布以下代码。

 class CircleTransitionAnimator: NSObject , UIViewControllerAnimatedTransitioning 
 {

        weak var transitionContext: UIViewControllerContextTransitioning?
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
            return 0.5;
        }



      @IBAction  func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
            self.transitionContext = transitionContext

            let containerView = transitionContext.containerView()
            let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) //as! ViewController

            let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) //as! ViewController

            containerView!.addSubview((fromVC?.view)!)


        let initialFrame =     CGRectMake(-fromVC!.view.frame.size.width/2,0, fromVC!.view.frame.size.height, fromVC!.view.frame.size.height ) as CGRect

            var  endFrame : CGRect     = CGRectMake(0, 0, 0, 0)

                    if toVC?.isKindOfClass(ViewController) == true  {
                        let viewToMove = toVC as! ViewController
                       let  cellForDismiss = viewToMove.cellViewToDismissTo

                        if cellForDismiss != nil {
                              endFrame     = cellForDismiss.frame as CGRect

                        }
                        self.transitionContext?.initialFrameForViewController(fromVC!)

                        let maskPath = UIBezierPath(rect: initialFrame)

                        let maskLayer =  CAShapeLayer()
                        maskLayer.frame          = toVC!.view.frame;
                        maskLayer.path           = maskPath.CGPath;


                        let  smallCirclePath =  UIBezierPath(rect: endFrame)
                        maskLayer.path = smallCirclePath.CGPath;
                        fromVC!.view.layer.mask = maskLayer





                        let pathAnimation = CABasicAnimation(keyPath: "path")
                        pathAnimation.fromValue  = maskPath.CGPath
                        pathAnimation.toValue   = smallCirclePath
                        pathAnimation.duration = self.transitionDuration(transitionContext)


                        let opacityAnimation =   CABasicAnimation(keyPath: "opacity")
                        opacityAnimation.fromValue = 1.0;
                        opacityAnimation.toValue   = 0.5;
                        opacityAnimation.duration  = self.transitionDuration(transitionContext)


                        CATransaction.begin()
                        CATransaction.setCompletionBlock({
                            transitionContext.completeTransition(transitionContext.transitionWasCancelled())
                            toVC!.view.layer.mask = nil
    fromVC!.view.layer.mask = nil
                            sourceSnap.removeFromSuperview()
                        })

                        maskLayer.addAnimation(pathAnimation, forKey: "pathAnimation")
                        maskLayer.addAnimation(opacityAnimation, forKey: "opacityAnimation")

                        CATransaction.commit()

            }
                    else{

                        if fromVC?.isKindOfClass(ViewController) == true  {

                            let viewToMove = fromVC as! ViewController
                           let cellForDismiss = viewToMove.cellViewToDismissTo

                            containerView!.addSubview(toVC!.view)

                            let circleMaskPathInitial = UIBezierPath(rect: cellForDismiss!.frame)
                            let extremePoint = CGPoint(x: cellForDismiss!.center.x - 0, y: cellForDismiss!.center.y - CGRectGetHeight(toVC!.view.bounds))
                            let radius = sqrt((extremePoint.x*extremePoint.x) + (extremePoint.y*extremePoint.y))

                            let circleMaskPathFinal = UIBezierPath(rect: CGRectInset(cellForDismiss!.frame, -radius, -radius))


                            let maskLayer = CAShapeLayer()
                            maskLayer.path = circleMaskPathFinal.CGPath
                            toVC!.view.layer.mask = maskLayer

                            let maskLayerAnimation = CABasicAnimation(keyPath: "path")
                            maskLayerAnimation.fromValue = circleMaskPathInitial.CGPath
                            maskLayerAnimation.toValue = circleMaskPathFinal.CGPath
                            maskLayerAnimation.duration = self.transitionDuration(transitionContext)
                            maskLayerAnimation.delegate = self
                            maskLayer.addAnimation(maskLayerAnimation, forKey: "path")
                        }
            }

        }
        override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
            self.transitionContext?.completeTransition(!self.transitionContext!.transitionWasCancelled())
            self.transitionContext?.viewControllerForKey(UITransitionContextFromViewControllerKey)?.view.layer.mask = nil
        }
    }

在另一个班级,我正在处理平移手势状态。

class NavigationControllerDelegate: NSObject , UINavigationControllerDelegate {
    @IBOutlet weak var navigationController: UINavigationController?
    var interactionController: UIPercentDrivenInteractiveTransition?
    var   transitionInProgress : Bool = false
    var   shouldCompleteTransition : Bool = false
    var   parentViewController : UIViewController!
    var percent : CGFloat!

    override func awakeFromNib() {
        super.awakeFromNib()
        //  Added Pan gesture to Navigatin Controller
        let panGesture = UIPanGestureRecognizer(target: self, action: Selector("panned:"))
        self.navigationController!.view.addGestureRecognizer(panGesture)

        let controller :[UIViewController] =   (self.navigationController?.viewControllers)!

        for contro in controller {
            if contro.isKindOfClass(ViewController) == true  {
                parentViewController = contro
            }
        }
    }
    @IBAction func panned(gestureRecognizer: UIPanGestureRecognizer) {

        let point : CGPoint =  gestureRecognizer .translationInView(self.parentViewController.view)
        self.percent = CGFloat( fmaxf(fminf(Float(point.y)   / 400.0 , 0.99), 0.0))
        let velocity : CGPoint = gestureRecognizer.velocityInView(self.parentViewController.view)

        // Percent is used for completing transaction , its value tells when the complete transition should start ( after the point when we stop sliding the view down )

        switch gestureRecognizer.state {
        case .Began:
            //
            self.transitionInProgress = true;
            self.interactionController = UIPercentDrivenInteractiveTransition()
            self.navigationController?.popViewControllerAnimated(true)

        case .Changed:
            // when we use swipe down then this block is continously called  and update the interactve transition
            self.shouldCompleteTransition = (Double(self.percent)  > 0.0 );

            let translation = gestureRecognizer.translationInView(self.navigationController!.view)
            let completionProgress = translation.x/CGRectGetWidth(self.navigationController!.view.bounds)
            self.interactionController?.updateInteractiveTransition(self.percent)
        case .Ended:

            // When swipe gesture ends , we finish the transition or in any other case "cancel" the transition
            self.transitionInProgress = false;
            if (self.shouldCompleteTransition  == false || gestureRecognizer.state == .Cancelled) {
                self.interactionController?.finishInteractiveTransition()
            }else{
                self.interactionController?.cancelInteractiveTransition()
            }

            self.interactionController = nil

        default:
            self.interactionController?.cancelInteractiveTransition()
            self.interactionController = nil
        }
    }

    func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CircleTransitionAnimator()
    }

    func navigationController(navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        return self.interactionController
    }

}

0 个答案:

没有答案