美文网首页
系统导航栏隐藏、显示、手势切换过程中存在问题总结

系统导航栏隐藏、显示、手势切换过程中存在问题总结

作者: 若水V_V | 来源:发表于2018-04-20 17:35 被阅读31次

    一、需求

    1、一个tabbar控制器包含多个子控制器,这里以2个控制器为例FirstViewController(简称FVC)和SecondViewController(简称SVC)。FVC首页需要隐藏导航栏,push到子控制器显示导航栏同时还要隐藏底部tabbar条;2、点击SVC需要先present一个LoginViewController(简称LVC)判断登陆与否才能进入.

    二、实现第一个需求隐藏导航栏

    2.1 在FVC增加下面两个方法

    override func viewWillDisappear(_ animated: Bool) {
             super.viewWillDisappear(animated)
            self.navigationController?.navigationBar.isHidden = false
        }
        override func viewWillAppear(_ animated: Bool) {
             super.viewWillAppear(animated)
            self.navigationController?.navigationBar.isHidden = true
        }
    

    得到效果图:


    1.gif

    感觉貌似都达到了我们的效果,可以如果你用手势返回的话,会发现顶部出现异常。


    2.gif
    所以这种方法不可行。
    2.2 进化版本

    还是原来两个方法基础,修改代码如下:

    override func viewWillDisappear(_ animated: Bool) {
             super.viewWillDisappear(animated)
             self.navigationController?.setNavigationBarHidden(false, animated: animated)
        }
        override func viewWillAppear(_ animated: Bool) {
             super.viewWillAppear(animated)
            self.navigationController?.setNavigationBarHidden(true, animated: animated)
        }
    
    3.gif

    这样就达到我们要求了,Tip:在进入子控制器FirstChildViewController后,如果想让导航栏颜色和view颜色都为蓝色,没有界线就像隐藏了导航栏一样的效果:


    image.png

    你只需要自定义导航栏中添加如下两行代码:

    bar.isTranslucent = false  //取消导航栏透明效果
    bar.shadowImage = UIImage() 
    

    三、实现第二个需求

    在AppDelegate实现UITabBarControllerDelegate协议方法

    //该方法在选择tabbaritem的时候调用
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
           
           if viewController == tabBarController.viewControllers?.last {
               let userIsLogin = UserDefaults.standard.bool(forKey: "userIsLogin")
               if !userIsLogin {
                   let storyboard = UIStoryboard(name: "Main", bundle: nil)
                   let loginRegister = storyboard.instantiateViewController(withIdentifier: String(describing: LoginViewController.self)) as! LoginViewController
                   let nav = HWQNaviController(rootViewController: loginRegister)
                  
                   self.tabbar.present(nav, animated: true, completion: nil)
               }
               return false
           }
           return true
           // UserDefaults.standard.setValue(true, forKey: "presentLoginRegister")
       }
    

    效果如下:
    功能实现,但发现一个bug,present时候,FVC顶部导航栏出现了;dismiss的时候FVC导航栏右消失了,看上去不协调。


    4.gif

    问题出现之前在FVC中实现了viewWillDisappear、viewWillAppear方法,消失的时候导航栏会出现,出现的时候导航栏会隐藏。为解决这个问题可以添加一个常量(presentLoginRegister),判断它消失之前是push进入自己的子控制器还是present到另外的控制器中。代码如下:

    //AppDelegate
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
            
           ........
                    //present到login时设置true
                    UserDefaults.standard.setValue(true, forKey: "presentLoginRegister")
                    self.tabbar.present(nav, animated: true, completion: nil)
                }
                return false
            }
            return true
            
        }
    //LoginViewController
    override func viewDidLoad() {
            super.viewDidLoad()
    
            let left = UIBarButtonItem(image: UIImage(named: "关闭"), style: .plain, target: self, action: #selector(closeBtnTapped))
            self.navigationItem.leftBarButtonItem = left
        }
        
        @objc func closeBtnTapped() {
            let tabbar = UIApplication.shared.keyWindow?.rootViewController as! HWQTabbarController
            tabbar.selectedIndex = 0
            //UserDefaults.standard.setValue(false, forKey: PresentLoginRegister)
            self.navigationController?.dismiss(animated: true, completion: nil)
        }
    //FVC
    override func viewWillDisappear(_ animated: Bool) {
             super.viewWillDisappear(animated)
            let presentLoginRegister = UserDefaults.standard.bool(forKey: "presentLoginRegister")
            if  !presentLoginRegister {
                self.navigationController?.setNavigationBarHidden(false, animated: animated)
            }
            
        }
    

    presentLoginRegister的值为true表示要进入Login,为false则为进入子控制器或其它。


    5.gif

    整个过程就解决了导航栏切换过程可能存在的bug。
    github地址:https://github.com/hwqll/HWQCustomNavigation

    相关文章

      网友评论

          本文标题:系统导航栏隐藏、显示、手势切换过程中存在问题总结

          本文链接:https://www.haomeiwen.com/subject/twfzkftx.html