iOS互动动画Swift

iOS互动动画Swift,ios,swift,animation,transition,interactive,Ios,Swift,Animation,Transition,Interactive,我一辈子都不明白这为什么不起作用 有两个风险投资公司:A和B 我想在VC A上向右滑动以显示VC B,但我想让它具有交互性,以便用户可以在两个VC之间拖动(就像在Instagram主屏幕上向左和向右滑动以转到相机和消息时一样)。目前,它不会“拖”。你可以在VC A上滑动,它将转到VC B 下面是要向右滑动的animator对象: class SlideRightTransitionAnimator: NSObject { let duration = 0.5 var isPresenting

我一辈子都不明白这为什么不起作用

有两个风险投资公司:A和B

我想在VC A上向右滑动以显示VC B,但我想让它具有交互性,以便用户可以在两个VC之间拖动(就像在Instagram主屏幕上向左和向右滑动以转到相机和消息时一样)。目前,它不会“拖”。你可以在VC A上滑动,它将转到VC B

下面是要向右滑动的animator对象:

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

}
这是我的交互式转换控制器

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

提前谢谢你

在VC A的viewDidLoad中,您将希望用UIPangestureRecognitor替换UIWipegestureRecognitor。然后在手势处理函数中实现适当的.changed状态


编辑:此外,为了实现控制器之间的滑动转换,我强烈建议改用UIPageViewController。这甚至可能是一个自定义UICollectionView解决方案。

在VC a的ViewDiLoad中,您需要将UIWipegestureRecognitor替换为UIPangestureRecognitor。然后在手势处理函数中实现适当的.changed状态


编辑:此外,为了实现控制器之间的滑动转换,我强烈建议改用UIPageViewController。这甚至可能是一个自定义UICollectionView解决方案。

在functionHandlePanesture中,您正在从VC a获取翻译参考(即,GestureRecognitor.view!.superview!) 但不是这样,而是从UIWindow中引用。(即,UIApplication.shared.windows.last

替换手势识别器。查看!。超级视图使用ui应用程序.shared.windows.last


在functionHandlePangestre中,您正在从VC A获取翻译参考(即GestureRecognitor.view!.superview!) 但不是这样,而是从UIWindow中引用。(即,UIApplication.shared.windows.last

替换手势识别器。查看!。超级视图使用ui应用程序.shared.windows.last


很抱歉回复太晚,但你是对的-关键是使用UIPageViewController。谢谢你迟来的回复,但你是对的-关键是使用UIPageViewController。谢谢
it's worked for me.