汉堡菜单UIPanGestureRecogniser

时间:2018-03-19 22:52:06

标签: ios swift uiview uipangesturerecognizer

我正在尝试以编程方式为我的应用程序制作一个汉堡包菜单并且不使用插件。我从基础开始,所以当用户向右滑动时,试图让2个UIViews一起工作。 2个视图是主视图和汉堡菜单。

到目前为止,UIViews加载到正确的位置,当用户向右滑动时,侧边栏会滑动。但是,当用户放开UIView时,滑动到UIView的中心也会固定在屏幕顶部。见下图:

enter image description here

一旦它迷失了,我就无法将它拉下来。我仍然可以左右滑动,但中心仍然受限于屏幕顶部。

我查看了我的代码,看不出我在做错了什么?

这是我的代码:

    class gestureSwipe: UIViewController, UIGestureRecognizerDelegate {

    let screenHeight = UIScreen.main.bounds.height
    let screenWidth = UIScreen.main.bounds.width

    var trayOriginalCenter: CGPoint!
    var sideBarSwipeLeftOffset: CGFloat!
    var siderBarSwipeRight: CGPoint!
    var sideBarSwipeLeft: CGPoint!

    let sideBarUIView: UIView! = {
        let sideBarUIView = UIView()
        sideBarUIView.backgroundColor = UIColor(red:1.0, green:0.0, blue:0.0, alpha:1.0)
        sideBarUIView.translatesAutoresizingMaskIntoConstraints = false
        sideBarUIView.isUserInteractionEnabled = true
        return sideBarUIView
    }()

    let mainView: UIView = {
        let mainView = UIView()
        mainView.backgroundColor = UIColor(red:0.0, green:1.0, blue:0.0, alpha:1.0)
        mainView.translatesAutoresizingMaskIntoConstraints = false
        mainView.isUserInteractionEnabled = true
        return mainView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        let settingsButton = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(HandleSettings))
        navigationItem.leftBarButtonItem = settingsButton
        view.backgroundColor = UIColor.white

        view.addSubview(mainView)
        view.addSubview(sideBarUIView)

        let SideBarPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didPan(sender:)))
        let MainViewPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didPan(sender:)))
        mainView.addGestureRecognizer(MainViewPanGestureRecognizer)
        sideBarUIView.addGestureRecognizer(SideBarPanGestureRecognizer)

        sideBarSwipeLeftOffset = 80
        siderBarSwipeRight = sideBarUIView.center
        sideBarSwipeLeft = CGPoint(x: sideBarUIView.center.x + sideBarSwipeLeftOffset, y: sideBarUIView.center.y)

        setupLayout()
    }


    @IBAction func didPan(sender: UIPanGestureRecognizer) {
        let velocity = sender.velocity(in: view)
        let translation = sender.translation(in: view)

        if sender.state == .began {
            trayOriginalCenter = sideBarUIView.center
        } else if sender.state == .changed {
            print("Gesture began")
            sideBarUIView.center = CGPoint(x: trayOriginalCenter.x + translation.x, y: trayOriginalCenter.y)
        } else if sender.state == .ended {
            print("Gesture ended")
            if velocity.x > 0 {
                UIView.animate(withDuration: 0.3) {
                    self.sideBarUIView.center = self.sideBarSwipeLeft
                }
            } else {
                UIView.animate(withDuration: 0.3) {
                    self.sideBarUIView.center = self.siderBarSwipeRight
                }
            }

        }
    }

    @IBAction func HandleSettings(sender : UIButton) {
        print ("Show settings")
    }

    private func setupLayout(){

        // CONSTRAINTS

        mainView.heightAnchor.constraint(equalToConstant: screenHeight).isActive = true
        mainView.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true

        sideBarUIView.heightAnchor.constraint(equalToConstant: screenHeight).isActive = true
        sideBarUIView.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true
        sideBarUIView.rightAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
    }

}

1 个答案:

答案 0 :(得分:0)

所以我想出了问题所在。在 sender.state == .ended 中,我使用的是 self.sideBarUIView.center = self.sideBarSwipeLeft ,它一直将视图推到屏幕中心。< / p>

修改

我决定从头开始制作汉堡菜单。从这个例子中汲取一些想法:https://github.com/iosapptemplates/drawer-menu-swift

然后我终于去了,并添加了一些不错的功能,如果菜单没有被刷过,它又被隐藏起来了。

如果有人需要,这是我的最终代码。

class hamburgerMenu: UIViewController, UIGestureRecognizerDelegate {

    let screenHeight = UIScreen.main.bounds.height
    let screenWidth = UIScreen.main.bounds.width
    var sideBarOriginalCenter: CGPoint!

    var mainView: UIView! = {
        let mainView = UIView()
        mainView.backgroundColor = UIColor(red:0.0, green:1.0, blue:0.0, alpha:1.0)
        mainView.translatesAutoresizingMaskIntoConstraints = false
        return mainView
    }()
    var overlayView: UIView! = {
        let viewBlack = UIView()
        viewBlack.backgroundColor = UIColor(red:0.0, green:0.0, blue:0.0, alpha:1.0)
        viewBlack.translatesAutoresizingMaskIntoConstraints = false
        return viewBlack
    }()
    var sideBarUIView: UIView! = {
        let sideBarUIView = UIView()
        sideBarUIView.backgroundColor = UIColor(red:1.0, green:0.0, blue:0.0, alpha:1.0)
        sideBarUIView.translatesAutoresizingMaskIntoConstraints = false
        return sideBarUIView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        let settingsButton = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(HandleSettings))
        navigationItem.leftBarButtonItem = settingsButton
        view.backgroundColor = UIColor.white

        view.addSubview(mainView)
        view.addSubview(overlayView)
        view.addSubview(sideBarUIView)

        overlayView.alpha = 0

        let swipeLeftGesture = UIPanGestureRecognizer(target: self, action: #selector(didPan(sender:)))
        mainView.addGestureRecognizer(swipeLeftGesture)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOverlay))
        mainView.addGestureRecognizer(tapGesture)

        setupLayout()

    }

    @IBAction func didPan(sender: UIPanGestureRecognizer) {
        let translation = sender.translation(in: view)

        if sender.state == .began {
            sideBarOriginalCenter = sideBarUIView.center
        } else if sender.state == .changed {
            sideBarUIView.center = CGPoint(x: sideBarOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
        } else if sender.state == .ended {
            let negHalfScreenWidth = ((self.screenWidth/2) * -1) / 2 // This should make -187.5 on iphoneX

            if sideBarUIView.center.x > negHalfScreenWidth {
                UIView.animate(withDuration: 0.3) {

                    if self.sideBarUIView.center.x > negHalfScreenWidth {
                        let leftSideOfScreen = self.screenWidth - self.screenWidth
                        self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
                    }
                }
            } else {
                UIView.animate(withDuration: 0.3) {
                    let leftSideOfScreen = (self.screenWidth / 2) * -1
                    self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
                }
            }
        }
    }

    @IBAction fileprivate func didTapOverlay() {
        UIView.animate(withDuration: 0.3, animations: {
            let leftSideOfScreen = (self.screenWidth / 2) * -1
            self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
        }) { (success) in
        }
    }

    @IBAction func HandleSettings(sender : UIButton) {
        if (sideBarUIView.center.x == 0) {
            UIView.animate(withDuration: 0.3, animations: {
                let leftSideOfScreen = (self.screenWidth / 2) * -1
                self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
            })
        } else if (sideBarUIView.center.x < -0.1) {
            UIView.animate(withDuration: 0.3, animations: {
                let leftSideOfScreen = self.screenWidth - self.screenWidth
                self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
            })
        }
    }

    private func setupLayout(){
        mainView.heightAnchor.constraint(equalToConstant: screenHeight).isActive = true
        mainView.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true

        sideBarUIView.rightAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
        sideBarUIView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        sideBarUIView.heightAnchor.constraint(equalToConstant: screenHeight).isActive = true
        sideBarUIView.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true

        overlayView.heightAnchor.constraint(equalToConstant: screenHeight).isActive = true
        overlayView.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true
    }

}