2016-10-06 3 views
0

Ich kann nicht für das Leben verstehen, warum das nicht funktioniert.iOS Interaktive Animation Swift

Haben zwei VCs: A und B.

ich direkt auf VC A Swipe will VC B offenbaren, sondern will es interaktiv machen, so dass ein Benutzer zwischen zwei VCs (wie auf Instagram Home-Bildschirm ziehen, wenn Wischen Sie nach links und rechts, um zur Kamera und den Nachrichten zu gelangen. Im Moment "schleppt" es nicht. Sie können auf VC A Swipe und es wird

Hier ist mein Animator Objekt gleiten Recht auf VC B. gehen:

class SlideRightTransitionAnimator: NSObject { 

let duration = 0.5 
var isPresenting = false 
let customInteractiveTransition = CustomInteractiveTransition() 

} 

// MARK: UIViewControllerTransitioningDelegate 
extension SlideRightTransitionAnimator: UIViewControllerTransitioningDelegate { 

// Return the animator when presenting a VC 
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
    isPresenting = true 
    return self 
} 

// Return the animator used when dismissing from a VC 
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
    isPresenting = false 
    return self 
} 

// Add the interactive transition for Presentation only 
func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 
    return customInteractiveTransition.transitionInProgress ? customInteractiveTransition : nil 
} 
} 

// MARK: UIViewControllerTransitioningDelegate 
extension SlideRightTransitionAnimator: UIViewControllerAnimatedTransitioning { 

// Return how many seconds the transiton animation will take 
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 
    return duration 
} 

// Animate a change from one VC to another 
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 

    // Get reference to our fromView, toView and the container view that we should perform the transition 
    let container = transitionContext.containerView 
    let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from)! 
    let toView = transitionContext.view(forKey: UITransitionContextViewKey.to)! 

    // Set up the transform we'll use in the animation 
    let offScreenRight = CGAffineTransform(translationX: container.frame.width, y: 0) 
    let offScreenLeft = CGAffineTransform(translationX: -container.frame.width, y: 0) 

    // Start the toView to the right of the screen 
    if isPresenting { 
     toView.transform = offScreenLeft 
    } 

    // Add the both views to our VC 
    container.addSubview(toView) 
    container.addSubview(fromView) 

    // Perform the animation 
    UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: [], animations: { 

     if self.isPresenting { 
      fromView.transform = offScreenRight 
      toView.transform = CGAffineTransform.identity 
     } 
     else { 
      fromView.transform = offScreenLeft 
      toView.transform = CGAffineTransform.identity 
     } 

     }, completion: { finished in 
      // Tell our transitionContext object that we've finished animating 
      transitionContext.completeTransition(true) 
    }) 
} 

} 

Hier ist mein Interactive Transition-Controller

class CustomInteractiveTransition: UIPercentDrivenInteractiveTransition { 

weak var viewController : UIViewController! 
var shouldCompleteTransition = false 
var transitionInProgress = false 
var completionSeed: CGFloat { 
    return 1 - percentComplete 
} 

func attachToViewController(viewController: UIViewController) { 
    self.viewController = viewController 
    setupPanGestureRecognizer(view: viewController.view) 
} 

private func setupPanGestureRecognizer(view: UIView) { 
    view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture))) 
} 

func handlePanGesture(gestureRecognizer: UIPanGestureRecognizer) { 
    let viewTranslation = gestureRecognizer.translation(in: gestureRecognizer.view!.superview!) 
    var progress = (viewTranslation.x/200) 
    progress = CGFloat(fminf(fmaxf(Float(progress), 0.0), 1.0)) 

    switch gestureRecognizer.state { 
    case .began: 
     transitionInProgress = true 
     viewController.dismiss(animated: true, completion: nil) 
    case .changed: 
     shouldCompleteTransition = progress > 0.5 
     update(progress) 
    case .cancelled, .ended: 
     transitionInProgress = false 
     if !shouldCompleteTransition || gestureRecognizer.state == .cancelled { 
      cancel() 
     } else { 
      finish() 
     } 
    default: 
     print("Swift switch must be exhaustive, thus the default") 
    } 
} 

} 

Und schließlich der Code für VC A:

class ViewControllerA: UITableViewController { 

let slideRightTransition = SlideRightTransitionAnimator() 
let customInteractiveTransition = CustomInteractiveTransition() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Add a Pan Gesture to swipe to other VC 
    let swipeGestureRight = UISwipeGestureRecognizer(target: self, action: #selector(swipeGestureRightAction)) 
    swipeGestureRight.direction = .right 
    view.addGestureRecognizer(swipeGestureRight) 
} 

    // MARK: Pan gestures 
func swipeGestureRightAction() { 
    performSegue(withIdentifier: "showMapSegue", sender: self) 
} 

// MARK: Prepare for segue 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

    if segue.identifier == "showVCB" { 

     // This gets a reference to the screen that we're about to transition to and from 
     let toViewController = segue.destination as UIViewController 

     // Instead of using the default transition animation, we'll ask the segue to use our custom SlideRightTransitionAnimator object to manage the transition animation 
     toViewController.transitioningDelegate = slideRightTransition 

     // Add the Interactive gesture transition to the VC 
     customInteractiveTransition.attachToViewController(viewController: toViewController) 
    } 
} 

Vielen Dank im Voraus !!!

Antwort

2

In Ihrer ViewDidLoad von VC A möchten Sie diesen UISwipeGestureRecognizer durch einen UIPanGestureRecognizer ersetzen. Implementieren Sie dann den entsprechenden .changed-Status in der Gestenhandler-Funktion.

EDIT: Um einen gleitenden Übergang zwischen den Controllern zu erreichen, empfehle ich, stattdessen einen UIPageViewController zu verwenden. Das oder vielleicht sogar eine benutzerdefinierte UICollectionView-Lösung.

+0

Sorry über die späte Antwort, aber ja, du hast recht - der Schlüssel ist UIPageViewController zu verwenden. Vielen Dank – Danny

0

in Funktion handlePanGesture Sie Übersetzung Referenz von VC A einnehmen (das heißt, gestureRecognizer.view! .superview!) aber statt dass nehmen referance von UIWindow. (Das heißt, UIApplication.shared.windows.last)

ersetzen gestureRecognizer.view! .superview! mit UIApplication.shared.windows.last

it's worked for me.