美文网首页Mac·iOS开发
iOS UITabBarController 嵌套 UINavi

iOS UITabBarController 嵌套 UINavi

作者: CeeYang | 来源:发表于2018-09-25 14:21 被阅读117次

    iOS UITabBarController 嵌套 UINavigationController

    本文处理两个问题:
    1. 自定义导航按钮后, 滑动返回手势失效问题
    2. TabBar 嵌套 NavigationBar 的 TabBar 显示隐藏错乱等问题
    

    主要思路

    1. 使用 UITabBarController 作为 Window 的 rootViewController
    2. 自定义 UINavigationController 控制器, 全局控制 tabbar 的显示与隐藏
    3. 添加自定义控制器为 UINavigationController 的 root 控制器
    4. UITabBarController 添加每个 UINavigationController 控制器

    直接上代码

    自定义的 UITabBarController :

    import UIKit
    
    class HomeTabBarController: UITabBarController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            createChildController()
        }
    
        /// 通过自定义方法添加所有子控制器
        func createChildController() {
            addChildVC(childVc: HomeViewController(), title: "首页", image: "IMG_Home", selectedImage: "IMG_Home_Selected")
            addChildVC(childVc: MoreViewController(), title: "应用", image: "IMG_More", selectedImage: "IMG_More_Selected")
            addChildVC(childVc: MineViewController(), title: "我的", image: "IMG_Mine", selectedImage: "IMG_Mine_Selected")
        }
    
        /// 自定义添加子控制器
        func addChildVC(childVc: UIViewController, title:String, image: String, selectedImage: String) {
            let nav = HomeNavigationController(rootViewController: childVc)
            let normalImage = UIImage(named: image)
            let selectedImage = UIImage(named: selectedImage)
            nav.navigationItem.title = title
            nav.tabBarItem = tabbarItem(with: title, normalImage: normalImage!, selectedImage: selectedImage!)
            addChildViewController(nav)
        }
    
        /// 快捷创建 UITabBarItem
        func tabbarItem(with title: String, normalImage: UIImage, selectedImage: UIImage) -> UITabBarItem{
            let image = normalImage.withRenderingMode(.alwaysOriginal)
            let _selectedImage = selectedImage.withRenderingMode(.alwaysOriginal)
            let tabBarItem = UITabBarItem(title: title, image: image, selectedImage: _selectedImage)
            tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.mainColor], for: .selected)
            tabBarItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.tabbarNormalColor], for: .normal)
            return tabBarItem
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    
    //让图片和文字在 iPad 下仍然保持上下排列
    extension UITabBar {
    
        override open var traitCollection: UITraitCollection {
            if UIDevice.current.userInterfaceIdiom == .pad {
                return UITraitCollection(horizontalSizeClass: .compact)
            }
            return super.traitCollection
        }
    }
    
    

    自定义的 UINavigationController :

    
    import UIKit
    
    class HomeNavigationController: UINavigationController, UIGestureRecognizerDelegate {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            /// 自定义返回按钮后返回手势失效
            /// 手动实现返回手势代理
            interactivePopGestureRecognizer?.delegate = self
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    
    
            /// 如果当前控制器的子控制器个数大于等于1, 说明推出的控制器为子控制器
            if childViewControllers.count > 0 {
    
                /// 自定义返回按钮
                let backBtn = UIButton()
                backBtn.setImage(UIImage(named: "IMG_Back"), for: .normal)
                backBtn.addTarget(self, action: #selector(backButtonDidClick), for: .touchUpInside)
                viewController.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backBtn)
    
                /// 子控制器隐藏  bottomBar
                viewController.hidesBottomBarWhenPushed = true
            }
            super.pushViewController(viewController, animated: animated)
        }
    
        /// 返回按钮点击事件
        @objc func backButtonDidClick() {
            popViewController(animated: true)
        }
    
        /// 滑动返回手势
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    
            /// 判断是否需要滑动返回手势
            if gestureRecognizer == navigationController?.interactivePopGestureRecognizer {
                return navigationController!.childViewControllers.count > 1
            }
    
            /// 解决当前控制器为根控制器的时候, 返回手势卡屏的问题
            if childViewControllers.count == 1 {
                return false
            }
    
            return true
        }
    }
    
    

    相关文章

      网友评论

        本文标题:iOS UITabBarController 嵌套 UINavi

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