2016-10-06 9 views
0

Я не могу понять, почему это не работает.iOS Интерактивная анимация Swift

Есть два VCs: A и B.

Я хочу красть прямо на VC A раскрыть VC B, но хотят, чтобы сделать его интерактивным, так что пользователь может перетаскивать между двумя VCs (как на Instagram Начального экрана вы проведите пальцем влево и вправо, чтобы перейти к камере и сообщениям). На данный момент он не «тянет». Вы можете провести на VC A, и он будет идти в ВК В.

Вот мой объект аниматор скользить вправо:

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) 
    }) 
} 

} 

Вот мой Интерактивное Transition контроллер

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") 
    } 
} 

} 

И, наконец, код 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) 
    } 
} 

Спасибо заранее!

ответ

2

В вашем представленииDidLoad от VC A вы захотите заменить этот UISwipeGestureRecognizer на UIPanGestureRecognizer. Затем выполните соответствующее состояние .changed в функции обработчика жеста.

EDIT: Кроме того, для достижения скользящего перехода между контроллерами, я настоятельно рекомендую использовать UIPageViewController. Это или, может быть, даже пользовательское решение UICollectionView.

+0

К сожалению о конце ответа, но да, вы правы - ключ использовать UIPageViewController. благодаря – Danny

0

в функции handlePanGesture вы принимаете ссылку перевода из VC A (т.е., gestureRecognizer.view! .superview!) , но вместо того, чтобы принять Referance от UIWindow. (То есть, UIApplication.shared.windows.last)

заменить gestureRecognizer.view! .superview! с UIApplication.shared.windows.last

it's worked for me.