【问题标题】:Back button does not work in Navigation Controller后退按钮在导航控制器中不起作用
【发布时间】:2020-11-22 17:07:25
【问题描述】:

我尝试为我的控制器实现一个后退按钮。

容器控制器内部的我的导航控制器实现:

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

我如何推动我需要弹出的控制器:

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),但它也不起作用......

【问题讨论】:

  • 首先,由于你的centerControllerUINavigationController 类型,所以你做centerController.navigationController?.popViewController 是没有意义的。您可以直接拨打centerController.popViewController(animated:)
  • 第二,看起来你正在推动一个导航控制器,并试图弹出另一个?您能否提供更多关于您的不同类如何相互关联的代码?
  • @Sylvan D Ash,我刚刚共享了完整的主控制器,您还需要更多吗?
  • 能否也包括配置MainController的类和推动视图控制器查看的类?
  • 我刚刚共享了我的容器控制器,视图由经典 UITableViewController 推送,在方法 'didSelectRowAt' 内

标签: ios swift controller uinavigationcontroller


【解决方案1】:

由于 UINavigationController 是 UIViewController 的子类,因此它具有 navigationController 属性。您不应该使用 UINavigationController 上的 navigationController 属性。所以你的代码应该是

centerController.popViewController(animated: true)

编辑: 正如“Sylvan D Ash”所提到的,您正在从 2 个不同的控制器中推送和弹出。

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

需要替换为

centerController.pushViewController(vc, animated: true)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 2011-11-29
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多