Кнопка возврата не работает в контроллере навигации - PullRequest
0 голосов
/ 02 августа 2020

Я пытаюсь реализовать кнопку возврата для своих контроллеров.

Моя реализация контроллера навигации внутри Контроллера контейнера:

func configureMainController(){
    let mainController = MainController()
    mainController.delegate = self
    mainController.backDelegate = self
    centerController = UINavigationController(rootViewController: mainController)
        
    view.addSubview(centerController.view)
    addChild(centerController)
    centerController.didMove(toParent: self)
}

Мой задний делегат:

extension ContainerController: BackDelegate {
    func handleBack() {
        print("ok")
        centerController.navigationController?.popViewController(animated: true)
    }
}

Кнопка «Назад» внутри главного контроллера:

navigationItem.rightBarButtonItem = UIBarButtonItem(image: image2?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(backAction))

@objc func backAction() -> Void {
    backDelegate?.handleBack()
}

Как я sh Контроллер, который мне нужно открыть:

DispatchQueue.main.async {
    let vc = ScienceController(collectionViewLayout: UICollectionViewFlowLayout())
    vc.modalPresentationStyle = .fullScreen
                    
    self.navigationController?.pushViewController(vc, animated: true)
}

Вот мой главный контроллер с соответствующими функциями :

class MainController: UIViewController {
    let tabBarCnt = UITabBarController()
    var delegate: MainControllerDelegate?
    var backDelegate: BackDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()

        createTabBarController()
    }
    
    @objc func backAction() -> Void {
        //self.navigationController?.popViewController(animated: true)
        backDelegate?.handleBack()
    }
    
    func checkIfUserIsLoggedIn(){
        if Auth.auth().currentUser?.uid == nil{
            performSelector(inBackground: #selector(handleLogout), with: nil)
        }
    }
    
    @objc func handleLogout(){
        do {
            try Auth.auth().signOut()
        } catch let logoutError {
            print(logoutError)
        }
        DispatchQueue.main.async {
            // UIView usage
            let loginController = LoginController()
            loginController.mainController = self
            loginController.modalPresentationStyle = .fullScreen
            
            self.present(loginController, animated: true, completion: nil)
        }
    }
    
    func createTabBarController() {
        let firstVc = Controller1()
        firstVc.title = "vc1"
        firstVc.view.backgroundColor =  UIColor.white
        firstVc.tabBarItem = UITabBarItem.init(title: "vc1", image: nil, tag: 0)
        
        let secondVc = Controller2()
        secondVc.title = "vc2"
        secondVc.view.backgroundColor =  UIColor.white
        secondVc.tabBarItem = UITabBarItem.init(title: "vc2", image: nil, tag: 1)

        let thirdVc = Controller3()
        thirdVc.title = "vc3"
        thirdVc.view.backgroundColor =  UIColor.white
        thirdVc.tabBarItem = UITabBarItem.init(title: "vc3", image: nil, tag: 2)
        
        let controllerArray = [firstVc, secondVc, thirdVc]
        tabBarCnt.viewControllers = controllerArray.map{
            UINavigationController.init(rootViewController: $0)}
        //tabBarCnt.selectedIndex = 1
        
        self.view.addSubview(tabBarCnt.view)
    }
}

Вот мой Контроллер Контейнера:

class ContainerController: UIViewController {
    
    // MARK: - Properties
    
    var menuController: MenuController!
    var centerController: UINavigationController!
    var isExpanded = false
    
    // MARK: - Init
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        configureMainController()
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .darkContent
    }
    
    override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation{
        return .slide
    }
    
    override var prefersStatusBarHidden: Bool{
        return isExpanded
    }
    
    // MARK: - Handlers
    
    func configureMainController(){
        let mainController = MainController()
        mainController.delegate = self
        mainController.backDelegate = self
        centerController = UINavigationController(rootViewController: mainController)
        
        view.addSubview(centerController.view)
        addChild(centerController)
        centerController.didMove(toParent: self)
    }
    
    func configureMenuController(){
        if menuController == nil{
            menuController = MenuController()
            menuController.delegate = self
            view.insertSubview(menuController.view, at: 0)
            addChild(menuController)
            menuController.didMove(toParent: parent.self)
        }
    }
    
    func animatePanel(shouldExpand: Bool, menuOption: MenuOption?){
        
        if shouldExpand{
            //show
            UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseInOut, animations: {
                self.centerController.view.frame.origin.x = self.centerController.view.frame.width - 80
            }, completion: nil)
        }
        else{
            //hide
            
            UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
                self.centerController.view.frame.origin.x = 0
            }) { (_) in
                guard let menuOption = menuOption else {return}
                self.didSelectMenuOption(menuOption: menuOption)
            }
            
        }
        
        animateStatusBar()
        
    }
    
    func didSelectMenuOption(menuOption: MenuOption){
        switch menuOption {
            
        case .Profile:
            let controller = ProfileController()
            present(UINavigationController(rootViewController: controller), animated: true, completion: nil)
            
        case .Settings:
            let controller = SettingsController()
            //controller.username = "pasha"
            present(UINavigationController(rootViewController: controller), animated: true, completion: nil)
            
        case .Logout:
            
            handleLogout()
            
        }
    }
    
    func animateStatusBar(){
        UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseInOut, animations: {
            self.setNeedsStatusBarAppearanceUpdate()
        }, completion: nil)
    }
    
    @objc func handleLogout(){
        
        do{
            try Auth.auth().signOut()
            DispatchQueue.main.async {
                UIApplication.shared.keyWindow?.rootViewController = LoginController()
            }
            //UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: true, completion: nil)
        } catch let logoutError {
            print(logoutError)
        }
      
    }
    
}

extension ContainerController: MainControllerDelegate {
    func handleMenuToggle(forMenuOption menuOption: MenuOption?) {
        if !isExpanded {
            configureMenuController()
        }
        
        isExpanded = !isExpanded
        animatePanel(shouldExpand: isExpanded, menuOption: menuOption)
    }
}

extension ContainerController: BackDelegate {
    
    func handleBack() {
        print("ok")
        centerController.popViewController(animated: true)
    }
        
}

Оператор print("ok") работает, но не centerController.navigationController?.popViewController(animated: true). Я тоже пробовал self.navigationController?.popViewController(animated: true) и тоже не работает ...

1 Ответ

0 голосов
/ 02 августа 2020

Поскольку UINavigationController является подклассом UIViewController, у него есть свойство navigationController. Вы не должны использовать свойство navigationController, присутствующее в UINavigationController. Таким образом, ваш код должен быть

centerController.popViewController(animated: true)

Изменить: Как упоминалось в «Sylvan DA sh», вы нажимаете и выскакиваете из двух разных контроллеров.

self.navigationController?.pushViewController(vc, animated: true)

необходимо заменить на

centerController.pushViewController(vc, animated: true)
...