0

我正在尝试实现一个滑动菜单,该菜单可以通过水平平移以交互方式解除,与 Uber 和 Google 应用程序中的菜单相同。一切都按预期进行,只是一旦我开始水平平移,就会在不跟随我的手指的情况下完成关闭。非常感谢任何有关问题所在的建议。

我进行了子类UIPresentationController化以定义我的菜单控制器的呈现宽度。我有自定义演示文稿动画师和解雇动画师,以及UIViewControllerTransitioningDelegate将它们全部返回到UIKit. 我还在gestureRecognizerShouldBegin(_ gestureRecognizer:)我的菜单控制器中实现了允许垂直滚动的方法。

在此处输入图像描述

SlideDismissAnimator

class SlideDismissAnimator: NSObject, UIViewControllerAnimatedTransitioning {

    let interactionController: SlideInteractionController?

    init(interactionController: SlideInteractionController?) {
        self.interactionController = interactionController
        super.init()
    }

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.2
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        let fromCV = transitionContext.viewController(forKey: .from)!

        let initialFrame = transitionContext.finalFrame(for: fromCV)
        var finalFrame = initialFrame
        finalFrame.origin.x = transitionContext.containerView.frame.width // My menu slides in from right

        let duration = transitionDuration(using: transitionContext)

        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
            fromCV.view.frame = finalFrame
        }) { _ in
   transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

滑动交互控制器

class SlideInteractionController: UIPercentDrivenInteractiveTransition {

    var interactionInProgress = false

    private var shouldCompleteTransition = false
    private weak var collectionViewController: UICollectionViewController!

    init(collectionViewController: UICollectionViewController) {
        super.init()
        self.collectionViewController = collectionViewController
        if let menuController = collectionViewController as? MenuController {
            let gesture = UIPanGestureRecognizer(target: self, action: #selector(handleGesture))
            menuController.collectionView?.addGestureRecognizer(gesture)
            gesture.delegate = menuController
        }
    }

    @objc func handleGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
        let translation = gestureRecognizer.translation(in: gestureRecognizer.view!.superview!)
        var progress = (translation.x / 100)
        progress = CGFloat(fminf(fmaxf(Float(progress), 0.0), 1.0))

        switch gestureRecognizer.state {
        case .began:
            interactionInProgress = true
            collectionViewController.dismiss(animated: true, completion: nil)

        case .changed:
            shouldCompleteTransition = progress > 0.5
            update(progress)

        case .cancelled:
            interactionInProgress = false
            cancel()

        case .ended:
            interactionInProgress = false
            if shouldCompleteTransition {
                finish()
            } else {
                cancel()
            }
        default:
            break
        }
    }
}

菜单控制器

class MenuController: UICollectionViewController, UIGestureRecognizerDelegate {

    var slideInteractionController: SlideInteractionController?

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
        slideInteractionController = SlideInteractionController(collectionViewController: self)
    }

    ...

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
            let translation = panGestureRecognizer.translation(in: collectionView)
            if translation.x > fabs(translation.y) {
                return true
            }
        }
        return false
    }
}
4

1 回答 1

0

我制作了一个示例项目,该项目在视图中使用 tableView,该视图充当在当前上下文中呈现的侧菜单抽屉

我的锅处理器

//MARK: Pan gesture Handler
    @objc func handlePanGesture(panGesture: UIPanGestureRecognizer)
    {
        ///Get the changes
        let translation = panGesture.translation(in: self.view)

        ///Make View move to left side of Frame
        if CGFloat(round(Double((panGesture.view?.frame.origin.x)!))) <= 0
        {
            panGesture.view!.center = CGPoint(x: panGesture.view!.center.x + translation.x, y: panGesture.view!.center.y)
            panGesture.setTranslation(CGPoint.zero, in: self.view)
        }

        ///Do not let View go beyond origin as 0
        if CGFloat(round(Double((panGesture.view?.frame.origin.x)!))) > 0
        {
            panGesture.view?.frame.origin.x = 0
            panGesture.setTranslation(CGPoint.zero, in: self.view)
        }

        ///States When Dragging
        switch panGesture.state
        {
        case .changed:
            self.setAlphaOfBlurView(origin: (panGesture.view?.frame.maxX)!)

        case .ended:
            if CGFloat(round(Double((panGesture.view?.frame.maxX)!))) >= self.view.frame.size.width*0.35
            {
                UIView.animate(withDuration: 0.7, animations: {
                    panGesture.view?.frame.origin.x = 0
                    panGesture.setTranslation(CGPoint.zero, in: self.view)
                })
            }
            else
            {
                UIView.animate(withDuration: 0.4, animations: {
                    panGesture.view?.frame.origin.x -= self.maximum_x
                    panGesture.setTranslation(CGPoint.zero, in: self.view)
                }, completion: { (success) in
                    if (success)
                    {
                        self.remove(asChildViewController: self.sideMenuVCObject, baseView: self.baseView)
                        self.baseView.removeFromSuperview()
                        self.blurView.removeFromSuperview()

                        //Remove Notification observer
                        NotificationCenter.default.removeObserver(self,name: NSNotification.Name(rawValue: "hideMenu"),object: nil)
                    }
                })
            }
            break
        default:
            print("Default Case")
        }
    }

GiHub 上的存储库链接

https://github.com/RockingGarg/Slide-Menu-Drawer.git

工作视频:

https://drive.google.com/open?id=13Q-bBkVlAX7uEweDyQGvNct-dXkBSveT

于 2018-02-05T05:27:29.833 回答