使用手势编程将子视图控制器添加到父View Controller

时间:2018-03-27 20:40:57

标签: ios swift xcode parent-child viewcontroller

我正在尝试以编程方式制作汉堡包菜单。到目前为止,我已经设法在使用UIViews并将手势附加到它们时构建一些有效(减去一些错误)的东西。

现在我想将UIViews换成名为的

的UIViewControllers
jobListController // This is the root controller
sideBarController // This is the side bar

如何将我的UIViewControllers添加到我的汉堡菜单类中,并应用我创建的手势,这些手势似乎在我的UIViews上正常工作。

我尝试使用addChildViewController(jobListController)添加它们,但这似乎不起作用。

我尝试将手势识别器添加到我的汉堡菜单类中的viewcontrollers但是我收到此错误:

  

输入' jobListController'没有会员' addGestureRecognizer'

我意识到这是因为我没有将视图控制器教给班级,但我只是在尝试。

我已经把头发撕了几天了,不知道怎么做,任何帮助都会很棒!

这是我的汉堡包菜单代码(我已经离开了UIViews,所以你可以看到我想要做的事情:

    class hamburgerMenu: UIViewController, UIGestureRecognizerDelegate {

    let screenHeight = UIScreen.main.bounds.height
    let screenWidth = UIScreen.main.bounds.width
    let statusBarWindow = UIApplication.shared.value(forKey: "statusBarWindow") as? UIWindow

    var sideBarOriginalCenter: CGPoint!
    var mainViewOriginalCenter: CGPoint!
    var navBarOriginalCenter: CGPoint!
    var statusBarShouldBeHidden = false

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


    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor.white
        navigationItem.title = "JOBS"
        let settingsButton = UIBarButtonItem(image: #imageLiteral(resourceName: "settingsImage"), style: .plain, target: self, action: #selector(HandleSettings))
        settingsButton.tintColor = UIColor(red:0.63, green:0.63, blue:0.63, alpha:1.0)
        settingsButton.width = 25
        navigationItem.leftBarButtonItem = settingsButton

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

        overlayView.isHidden = true

        configureGestures()
        setupLayout()

    }

    override var prefersStatusBarHidden: Bool {
        return statusBarShouldBeHidden
    }

    override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
        return .fade
    }

    fileprivate func configureGestures() {

        let swipeMainViewGesture = UIPanGestureRecognizer(target: self, action: #selector(didPanMainView))
        mainView.addGestureRecognizer(swipeMainViewGesture)

        let swipeOverlayViewGesture = UIPanGestureRecognizer(target: self, action: #selector(didPanOverlayView))
        overlayView.addGestureRecognizer(swipeOverlayViewGesture)

        let swipeSideBarGesture = UIPanGestureRecognizer(target: self, action: #selector(didPanSideBar(sender:)))
        sideBarUIView.addGestureRecognizer(swipeSideBarGesture)

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

    @IBAction func didPanMainView(sender: UIPanGestureRecognizer) {

        let translation = sender.translation(in: view)

        if sender.state == .began {

            sideBarOriginalCenter = sideBarUIView.center
            mainViewOriginalCenter = overlayView.center
            navBarOriginalCenter = navigationController?.navigationBar.center
            overlayView.isHidden = false

            UIView.animate(withDuration: 0.25) {
                self.setNeedsStatusBarAppearanceUpdate()
            }

        } else if sender.state == .changed {

            sideBarUIView.center = CGPoint(x: sideBarOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            overlayView.center = CGPoint(x: mainViewOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            mainView.center = CGPoint(x: mainViewOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            navigationController?.navigationBar.center = CGPoint(x: navBarOriginalCenter.x + translation.x, y: navBarOriginalCenter.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)
                        self.overlayView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
                        self.mainView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
                        self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth ,y: self.navBarOriginalCenter.y)
                    }
                }
            } else {
                UIView.animate(withDuration: 0.3) {

                    let leftSideOfScreen = (self.screenWidth / 2) * -1

                    self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
                    self.overlayView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
                    self.mainView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
                    self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth/2 ,y: self.navBarOriginalCenter.y)
                    self.overlayView.isHidden = true

                    // Hide the status bar
                    self.statusBarShouldBeHidden = false
                    self.setNeedsStatusBarAppearanceUpdate()
                }
            }
        }
    }

    @IBAction func didPanOverlayView(sender: UIPanGestureRecognizer) {

        let translation = sender.translation(in: view)

        if sender.state == .began {

            sideBarOriginalCenter = sideBarUIView.center
            mainViewOriginalCenter = overlayView.center
            navBarOriginalCenter = navigationController?.navigationBar.center
            overlayView.isHidden = false

            UIView.animate(withDuration: 0.25) {
                self.setNeedsStatusBarAppearanceUpdate()
            }

        } else if sender.state == .changed {

            sideBarUIView.center = CGPoint(x: sideBarOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            overlayView.center = CGPoint(x: mainViewOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            mainView.center = CGPoint(x: mainViewOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            navigationController?.navigationBar.center = CGPoint(x: navBarOriginalCenter.x + translation.x, y: navBarOriginalCenter.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)
                        self.overlayView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
                        self.mainView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
                        self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth ,y: self.navBarOriginalCenter.y)
                    }
                }
            } else {
                UIView.animate(withDuration: 0.3) {

                    let leftSideOfScreen = (self.screenWidth / 2) * -1

                    self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
                    self.overlayView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
                    self.mainView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
                    self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth/2 ,y: self.navBarOriginalCenter.y)
                    self.overlayView.isHidden = true

                    self.statusBarShouldBeHidden = false
                    self.setNeedsStatusBarAppearanceUpdate()
                }
            }
        }
    }

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

        if sender.state == .began {

            sideBarOriginalCenter = sideBarUIView.center
            mainViewOriginalCenter = overlayView.center
            navBarOriginalCenter = navigationController?.navigationBar.center
            overlayView.isHidden = false

            UIView.animate(withDuration: 0.3) {
                self.statusBarWindow?.alpha = 0.0
            }

        } else if sender.state == .changed {

            sideBarUIView.center = CGPoint(x: sideBarOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            overlayView.center = CGPoint(x: mainViewOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            mainView.center = CGPoint(x: mainViewOriginalCenter.x + translation.x, y: sideBarUIView.center.y)
            navigationController?.navigationBar.center = CGPoint(x: navBarOriginalCenter.x + translation.x, y: navBarOriginalCenter.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)
                        self.overlayView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
                        self.mainView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
                        self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth ,y: self.navBarOriginalCenter.y)
                    }
                }
            } else {

                UIView.animate(withDuration: 0.3) {
                    let leftSideOfScreen = (self.screenWidth / 2) * -1
                    self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
                    self.overlayView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
                    self.mainView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
                    self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth/2 ,y: self.navBarOriginalCenter.y)
                    self.overlayView.isHidden = true
                    self.statusBarWindow?.alpha = 1.0
                }
            }
        }
    }

    @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)
            self.overlayView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
            self.mainView.center = CGPoint(x: self.screenWidth/2 ,y: self.sideBarUIView.center.y)
            self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth/2 ,y: self.navBarOriginalCenter.y)
            self.overlayView.isHidden = true
            self.statusBarWindow?.alpha = 1.0
        }) { (success) in
        }
    }

    @IBAction func HandleSettings(sender : UIButton) {

        self.navBarOriginalCenter = self.navigationController?.navigationBar.center

        UIView.animate(withDuration: 0.3, animations: {
            let leftSideOfScreen = self.screenWidth - self.screenWidth

            self.sideBarUIView.center = CGPoint(x: leftSideOfScreen ,y: self.sideBarUIView.center.y)
            self.overlayView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
            self.mainView.center = CGPoint(x: self.screenWidth ,y: self.sideBarUIView.center.y)
            self.navigationController?.navigationBar.center = CGPoint(x: self.screenWidth ,y: self.navBarOriginalCenter.y)
            self.statusBarWindow?.alpha = 0.0
        })
        overlayView.isHidden = false
   }

    private func setupLayout(){

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

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

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

我的2个控制器的代码,代码完全相同,除了我上面提到的类名:

class sideBarController:UIViewController {

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

    var greyBackground: UIView! = {
        let greyBackground = UIView()
        greyBackground.backgroundColor = UIColor(red:0.18, green:0.20, blue:0.21, alpha:1.0)
        greyBackground.translatesAutoresizingMaskIntoConstraints = false
        return greyBackground
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(greyBackground)
        setupLayout()
    }
    private func setupLayout(){
        greyBackground.rightAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
        greyBackground.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        greyBackground.heightAnchor.constraint(equalToConstant: screenHeight).isActive = true
        greyBackground.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true
    }
}

1 个答案:

答案 0 :(得分:1)

我假设jobListController是一个UIViewController?您需要在其视图中添加手势识别器(jobListController.view)。不确定这是否是您遇到的唯一问题,但这将解决崩溃问题。