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

一、需求

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

你可能感兴趣的:(系统导航栏隐藏、显示、手势切换过程中存在问题总结)