complateTransition不会忽视swift 2

时间:2015-08-30 21:02:58

标签: ios animation transition swift2

我正在尝试使用此类设置交互式转换:

class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerInteractiveTransitioning, UIViewControllerTransitioningDelegate, UIViewControllerContextTransitioning {

weak var transitionContext: UIViewControllerContextTransitioning?

var sourceViewController: UIViewController! {
    didSet {
        enterPanGesture = UIScreenEdgePanGestureRecognizer()
        enterPanGesture.addTarget(self, action:"panned:")
        enterPanGesture.edges = UIRectEdge.Left
        sourceViewController.view.addGestureRecognizer(enterPanGesture)
    }
}
var togoSourceViewController: UIViewController!

let duration    = 1.0
var presenting  = true
var reverse = false
var originFrame = CGRectNull
var shouldBeInteractive = false

private var didStartedTransition = false
private var animated = false
private var interactive = false
private var AnimationStyle = UIModalPresentationStyle(rawValue: 1)
private var didFinishedTransition = false
private var percentTransition: CGFloat = 0.0
private var enterPanGesture: UIScreenEdgePanGestureRecognizer!
private var tovc = UIViewController()
private var pointtovc = CGPoint()
private var pointfromvc = CGPoint()
private var fromvc = UIViewController()
private var generalcontainer = UIView()

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    animated = true

    let container = transitionContext.containerView()
    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!

    if reverse {
        toViewController.view.center.x -= (container?.bounds.size.width)!
        container?.insertSubview(toViewController.view, aboveSubview: fromViewController.view)
    } else {
        toViewController.view.center.x += (container?.bounds.size.width)!
        container?.addSubview(toViewController.view)
    }

    UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions.TransitionNone, animations: {
        if self.reverse {
            toViewController.view.center.x += (container?.bounds.size.width)!
        } else {
            toViewController.view.center.x -= (container?.bounds.size.width)!
        }
        }, completion: { finished in
            transitionContext.completeTransition(true)
            self.animated = false
            self.reverse = !self.reverse
    })
}

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
    return duration
}

func startInteractiveTransition(transitionContext: UIViewControllerContextTransitioning) {

    interactive = true
    animated = true

    let container = transitionContext.containerView()
    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)! //ArticleView
    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)! //Article OU Favoris

    if reverse {
        toViewController.view.frame.origin.x = -fromViewController.view.frame.maxX
        container?.insertSubview(toViewController.view, aboveSubview: fromViewController.view)
    }
    tovc = toViewController
    pointtovc = toViewController.view.bounds.origin
    fromvc = fromViewController
    pointfromvc = fromViewController.view.bounds.origin
    generalcontainer = container!
}

func containerView() -> UIView? {
    return sourceViewController?.view
}

func viewControllerForKey(key: String) -> UIViewController? {
    return sourceViewController?.storyboard!.instantiateViewControllerWithIdentifier(key)
}

func viewForKey(key: String) -> UIView? {
    return sourceViewController?.storyboard!.instantiateViewControllerWithIdentifier(key).view
}

func initialFrameForViewController(vc: UIViewController) -> CGRect {
    return vc.view.frame
}

func finalFrameForViewController(vc: UIViewController) -> CGRect {
    return vc.view.frame
}

func isAnimated() -> Bool {
    return animated
}

func isInteractive() -> Bool {
    return interactive
}

func presentationStyle() -> UIModalPresentationStyle {
    return AnimationStyle!
}

func completeTransition(didComplete: Bool) {
    interactive = false
    animated = false
    shouldBeInteractive = false
    didFinishedTransition = didComplete
    transitionContext?.finishInteractiveTransition()
    transitionContext?.completeTransition(true)
}

func updateInteractiveTransition(percentComplete: CGFloat) {
    if self.reverse {
        print(percentComplete)
        self.tovc.view.frame.origin.x = (self.fromvc.view.frame.maxX * (percentComplete)) - self.fromvc.view.frame.maxX
    }
}

func finishInteractiveTransition() {
    UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions.TransitionNone, animations: {
        if self.reverse {
            self.tovc.view.frame.origin.x = self.fromvc.view.frame.origin.x
        }
        }, completion: { finished in
            self.animated = false
            self.reverse = !self.reverse
            self.completeTransition(true)
    })
}

func cancelInteractiveTransition() {
    UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions.TransitionNone, animations: {
        if self.reverse {
            self.tovc.view.frame.origin.x = -self.fromvc.view.frame.maxX
        }
        }, completion: { finished in
            self.animated = false
            self.completeTransition(true)
    })
}

func transitionWasCancelled() -> Bool {
    return didFinishedTransition
}

func targetTransform() -> CGAffineTransform {
    return CGAffineTransform()
}

func completionSpeed() -> CGFloat {
    return 1 - percentTransition
}

func panned(pan: UIPanGestureRecognizer) {
    switch pan.state {
    case .Began:
        animated = true
        shouldBeInteractive = true
        didStartedTransition = true
        didFinishedTransition = false
        sourceViewController?.dismissViewControllerAnimated(true, completion: nil)
        updateInteractiveTransition(0)
        break
    case .Changed:
        percentTransition = CGFloat(pan.translationInView(sourceViewController!.view).x / sourceViewController!.view.frame.width)
        if percentTransition < 0.0 {
            percentTransition = 0.0
        } else if percentTransition > 1.0 {
            percentTransition = 1.0
        }
        updateInteractiveTransition(percentTransition)
        break
    case .Ended, .Failed, .Cancelled:
        animated = false
        shouldBeInteractive = false
        didStartedTransition = false
        didFinishedTransition = true
        if percentTransition < 0.8 {
            cancelInteractiveTransition()
        } else {
            finishInteractiveTransition()
        }
        break
    case .Possible:
        break
    }
}

}

animateTransition效果很好并且解除了我的fromViewController,但是当我调用InteractiveTransition然后调用finishInteractiveTransition()completeTransition(true)期间,我仍然有我的观点:

enter image description here

但在Apple上他们说:

  

您必须在动画完成后调用此方法,以通知系统已完成过渡动画。您传递的参数必须指示动画是否成功完成。对于交互式动画,除了finishInteractiveTransition或cancelInteractiveTransition方法之外,还必须调用此方法。调用此方法的最佳位置是动画的完成块。

那么,我做错了什么?

我正在使用ios9,swift 2,Xcode 7 beta 6

1 个答案:

答案 0 :(得分:1)

我找到了解决方案:

我应该在功能transitionContext.completeTransition(true)中致电finishInteractiveTransition(),但我之前的代码transitionContextstartInteractiveTransition(transitionContext: UIViewControllerContextTransitioning)

中的代码不同

所以我添加一个变量:

private var Context: UIViewControllerContextTransitioning?

并用它来打电话:

transitionContext.completeTransition(true)

transitionContext.completeTransition(false)