【发布时间】:2015-08-30 21:02:57
【问题描述】:
我正在尝试使用此类设置交互式过渡:
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) 时,我仍然有我的两种观点:
但在苹果上他们说:
您必须在动画完成后调用此方法以通知系统过渡动画已完成。您传递的参数必须指示动画是否成功完成。对于交互式动画,除了finishInteractiveTransition 或cancelInteractiveTransition 方法外,您还必须调用此方法。调用此方法的最佳位置是在动画的完成块中。
那么,我做错了什么?
我正在使用 ios9、swift 2、Xcode 7 beta 6
【问题讨论】:
-
我注意到你总是说
completeTransition(true)。那是错误的。你必须传递一个布尔值来说明我们是否被取消。如果转换已完成,则必须通过true,如果已取消,则必须通过false。 -
哦,这是个错误。我在
ancelInteractiveTransition()中更正了这一点,现在称为self.completeTransition(false)
标签: ios animation transition swift2